I'm really interested - why do you need to put
readln;
line after reading some value from keyboard into variable? For example,
repeat
writeln('Make your choise');
read(CH);
if (CH = '1') then begin
writeln('1');
end;
{ ... }
until CH = 'q';
If you run the following code, and press '1' on keyboard, you get an output like
1
Make your choise
Make your choise
Make your choise
On the other hand, if you add that "readln;" line, it all works perfect:
repeat
writeln('Make your choise');
read(CH);
readln;
if (CH = '1') then begin
Writeln('1');
end
until CH = 'q';
My only guess is that calling readln without arguments terminates the process of reading the keyboard input. But if so, why cant the read/readln functions stop reading input themselves, to avoid such a clumsiness?
read reads a character, but still expects Enter to be pressed before returning, even though it only returns 1 character. You're pressing Enter after 1, and the console is stuffing the keyboard buffer with a CR (ASCII 0xd) and a LF (ASCII 0xa). (On a Linux/UNIX system, Make your choise will only appears twice, because UNIX uses only a LF as its linefeed character). You can see these by printing the values of the character received with ord(CH) (iirc).
The second program is pulling the CRLF combo out of the keyboard buffer with the subsequent readln and discarding it, so it behaves in the way you seem to want.
If this is a throwaway program, just do it via readln, and go on to solve whatever more important problem you're working on. If it's destined for production, build up an input function via a loop of some sort around readkey (which returns immediately after one character).
Thanks for the nostalgia.
Related
I have a Linux distribution, and I'd like to be able to detects a wide range of keys, but I can't figure out how to distinguish the press of the Escape key, versus a key detected as keypress.
If I use this:
require 'io/console'
puts STDIN.raw { STDIN.getc }
and press, say, Arrow up, the interpreter will return immediately \e, then on subsequent getc calls, without pressing any key, it will return the remaining chars of the escape sequence ([ and A).
The problem is that, after the first getc call, I don't know if the user has actually pressed Esc, or another key which generates an escape sequence.
Is it possible to make the distinction between the two cases, without multiple getc invocations?
I don't think so, because the character input is done at a higher level than the physical keyboard. That is, by design, an ESC character read by getc is an ESC character, no matter how on the keyboard it was input (or not input on the keyboard at all, for example, by redirection).
I don't think Ruby out of the box has a way to detect hardware events such as keyboard presses. There is IOCTL for lower level device access, but I don't know how to use it for your purpose. But even if you could, how would you handle alternate keyboard layouts? What you expect to be an ESC key might be mapped to a different character.
There is a read_nonblock method on $stdin that you might use to see if there is an additional character in the buffer immediately after reading the ESC key. If so, it's likely that a special character other than ESC was pressed. If not, it's likely the ESC key was pressed.
signal test : std_logic_vector(135 downto 0) := x"FC255346D1B5ED025D57B49D1B44D584A1";
this signal corresponds to 'Hello World' on the console. It is not hexadecimal, obviously not binary. What is it ? I am trying to write something different.
FC255346D1B5ED025D57B49D1B44D584A1 is in binary:
111111000010010101010011010001101101000110110...
111111: UART is in high level (no transmission)
0: start bit
00010010: This is 'H' in ASCII binary (LSB first)
1: End of character
010100110: This is 'e' in ASCII binary (LSB first)
etc...
Well it begins X" ..." so it's obviously hexadecimal.
That's not the question, nor is what does it represent? which is obviously "Hello World", but how it represents it.
Figure out what's between it and the console.
If just a shift register, figure out which end comes out first. write out the first 16 bits or so - or draw the waveform - remembering that a console's interface is a UART, which expects start bits, 7 or 8 bit data, possibly parity, stop bits.
Examine these to find out where Ascii "H" is buried and reverse engineer the rest of the spec from that.
Then you'll know what you have to do to substitute another message.
If you pad out the actual data with these other formatting bits in the std_logic_vector, you can replace the transmit part of a UART with a simple shift register - it's a neat hack, moving complexity out of the actual hardware and into something else - Python script or simple VHDL profram - to take a string and convert it to this format - and that's my guess what's happened here.
You might look around the rest of the project to see if you can find that python script or program...
I'm building an embedded system that talks RS-232 to a serial terminal, "full-duplex" style, so the host echos what the terminal sends.
I know printables (at least ASCII 0x20 to 0x7E) are normally echoed, but which control characters (if any) are normally echoed in a case like this?
Is there some Posix or other standard for this? How does Linux do it?
For example, if I type a ^C at the terminal, should the ^C be echoed by the host? What about ^G (bell)? Etc?
I'll try to answer my own question. Here's what I'm planning to do:
Printables (ASCII 0x20 to 0x7E) are echoed.
CR is echoed as CR LF (because the Enter key on terminals normally
sends CR, and an ANSI terminal requires CR to move the cursor to the
left, and LF to move it to the next line).
BS (backspace, 0x08) and DEL (0x7F) are treated identically and are
echoed as "\b \b" (in C syntax) - that is, backspace, space,
backspace, to erase the last character on the terminal.
All other control characters are not echoed. (Not to say they're not processed, but they're not automatically echoed. What they do is outside the scope of what I'm asking about.)
My reasoning is that the remaining control characters are usually meant to do something, and that something is meant to happen at the host, not at the terminal.
For example DC1/DC3 (^Q/^S) are often used as flow control ("XON/XOFF") - it doesn't make sense to echo the ^S (XOFF) back to the terminal, since the purpose is to flow control the host. Echoing XOFF back to the terminal would flow control the terminal, clearly not what was intended. So echoing this makes no sense.
Similarly, ANSI escape sequences sent by the terminal (cursor up/down/left/right, etc.) should not be echoed.
Bottom line - echo printables only. Control characters as a rule should not be echoed, except on a case-by-case basis depending on their function (carriage return, backspace, etc.).
I'd like comments on whether or not this is the right thing to do (and why).
I'm writing a snake game for the terminal, i.e. output via print.
The following works just fine:
while status[snake_monad] do
print to_string draw canvas, compose_all([
frame,
specs,
snake_to_hash(snake[snake_monad])
])
turn! snake_monad, get_dir
move! snake_monad, specs
sleep 0.25
end
But I don't want the turn!ing to block, of course. So I put it into a new Thread and let it loop:
Thread.new do
loop do
turn! snake_monad, get_dir
end
end
while status[snake_monad] do
...
# no turn! here
...
end
Which also works logically (the snake is turning), but the output is somehow interspersed with newlines. As soon as I kill the input thread (^C) it looks normal again.
So why and how does the thread have any effect on my output?
And how do I work around this issue? (I don't know much about threads, even less about them in ruby. Input and output concurrently on the same terminal make the matter worse, I guess...)
Also (not really important): Wanting my program as pure as possible, would it be somewhat easily possible to get the input non-blockingly while passing everything around?
Thank you!
You don't want non-blocking IO - you want unbuffered IO.
There's no need for threads, here - you just need to put your terminal into the right mode and then wait for the keypress on the main event loop.
Here's a completely ridiculous example.
require 'io/wait'
def ping
term = `stty -g`
`stty raw -echo cbreak`
loop do
if STDIN.ready?
#command thy snake!
ret = STDIN.getc
end
if ret
#process the snake command if there was one
STDOUT.write("you told the snake to #{ret}\n")
else
#slither around bitin' fools and hustling apples.
end
end
ensure
`stty #{term}`
end
I found a dirty solution:
I just had to add a carriage return (\r) after each newline in the to_string function, so everything that gets printed after it will be overwritten. Since it was a newline, it loses its effect. Everything seems fine now.
But I'd much rather know why this happens and fix it (if possible) cleanly.
When I type any key, normally, it is immediately echoed back to the std output i.e.my screen.
If I have to enter a password, that says that it will not echo back, I cannot see the keys that I type.
How does this work.
Does each key press go to the kernel immediately(without me pressing ENTER), and then the kernel decides to echo them or not?
Like , I press 'A', it goes to the kernel; kernel echoes it; I get it on my screen. Now I hit 'B'...same sequence again...; Now I have 'AB' on my screen (my command) and hit ENTER; My command goes to the kernel and is finally executed.
Is there any other explanation? What happens in the background during the key presses?
The terminal driver in the kernel can be put in several modes (there are actually many more flags than this, and these days "cbreak" is actually the opposite of a different flag, so this is simplified).
The "cbreak" mode means that the process that is attempting to read from the terminal will receive keyboard input as soon as it is available. When cbreak mode is off, the data is stored by the kernel in a buffer until enter is pressed, and certain keys like backspace are handled by the kernel (when you press backspace, it removes the character from the buffer and - if echo mode is on - writes "backspace-space-backspace" to the terminal to overwrite the character with a blank space).
Echo mode means that whenever the user presses a key, the kernel will immediately echo it back to the screen. When it is off, nothing will be echoed to the screen, and the program will need to write it to the terminal if it wants you to see it.
There are several typical situations:
In programs that do advanced input handling (like most shells, or something like a full screen program), cbreak is on and echo is off; the program will write the character to the terminal itself if it is not part of a special key escape sequence.
In most situations [the default with a simple program that reads stdin and writes stdout], echo is on and cbreak is off. When you type, it behaves as I described above, all of this is handled by the kernel until you hit enter and it sends it to the application. Input editing is limited to backspace [and ctrl-u, ctrl-w], trying to use the arrow keys will just put escape sequences like ^[[D in the input line.
When reading a password, echo is off and cbreak is off. Input works just like the default case, except the kernel does not copy input to the screen.
The program that is running tells the kernel what mode to have it in with the termios functions. You can use the stty command to do the same in a shell environment, but be aware that this may interfere with the shell's own input handling or with what programs you run expect the default state to be.
Your keyboard generates electrical signals that are eventually interpreted as keycodes that correspond to letters - 'A', 'B', function keys F1, F2 etc. This all happen in the keyboard driver that is handled by the kernel. That keyboard driver has a buffer to receive all the keypresses from the keyboard and sends that to the kernel that in turn direct them to processes that is currently having the focus. What to do with the sequence of keys are totally decided by the individual application, such as whether to display the keys or not.
echo program is part of coreutils. You can download its sources here. Look at src/echo.c it's quite small. You can see that echo uses fputc or putchar calls. Those calls deal with standard stream called stdout. The architecture of standard streams is quite complicated and it's beyond of this post. You can found it using for example google.