Issue
I am trying to write a simple text editor in c++ for Linux. This requires a while loop that reads characters from the terminal, and, so far, I simply display their ASCII values. The problem is that using different input functions results in different outputs.
If i use read()
to get the characters from the terminal, I have to manually flush the buffer after every cout
to get output after every key press, something like:
char c = '0';
while ((read(STDIN_FILENO, &c, 1) == 1) && c != 'q') {
cout << std::hex << (int)c<<std::flush;
}
If I do not do this, I get output only after the while loop ends, i.e. if I press q
.
On the other hand, if i use cin.get()
, then I do not run into any issues. I can simply do
char c = '0';
while (cin.get(c) && c != 'q') {
cout << std::hex << (int)c;
}
For context and since I don't know what kind of issue this is, these are some details of my system:
OS: Debian GNU/Linux 12 (bookworm) x
Host: Blade 14 - RZ09-0370 1.04
Kernel: 6.1.0-17-amd64
Shell: zsh 5.9
DE: GNOME 43.9
Thanks in advance!
Solution
The difference is that cin.get
is synchronized with stdout because there's explicit code for that in the std::stream library (see std::basic_ios<CharT,Traits>::tie
).
If instead you read directly from stdin
file descriptor you're bypassing the standard library streams completely, and the output is not flushed before the input because the library doesn't know you're asking for an input.
PS: If you're writing an editor running in a terminal in linux probably you should use ncurses
library that takes care of a lot of these details and can also handle all key combos and specials (like arrows, function keys, shift, ctrl and the like).
Answered By - 6502 Answer Checked By - Clifford M. (WPSolving Volunteer)