0

I'm writing a program where it involves creating a prompt that reads input from stdin. The actual code is large and the scope of this problem resides in the following snippet of code. Here's a simple layout of the code -

char _buf[1];
while(*_buf!='q') { 
  printf(">>> ");
  read(0, _buf, 1);
}

when running the compiled code, I would expect the stdout to look something like the following -

>>> <stdin input>

but instead, nothing is being written out to stdout, or to be more specific, nothing in the same line of stdin is being shown. If I add a \n at the end of the string output >>>, it enables it to show up in stdout, namely

>>>
<stdin input>

Now, I want to put up some constraints as to what i can and can not use. I just want to use the wrapper function read() to read syscall directly instead of using something like fscanf(3) or other similar libc functions.

If I modify the above code with only consisting of syscalls (e.g replacing printf() with write()). I do get the character string printed out before it is reading from stdin, likeso

int main() {
    char _buf[1];
    while(*_buf!='q') {
        write(fileno(stdout),">>> ", 4);
        read(fileno(stdin),_buf,1);
        write(fileno(stdout), "\n", 1);
    }
}

but something unexpected happens, the char string >>> is being printed out to stdout equal to the length of input is given to stdin.

>>> a
>>>
>>> aa
>>>
>>>
>>> aaa
>>>
>>>
>>>

given length 1 of input string, a prints out >>> one time, aa 2 times, aaa 3 times and so on. I don't quite understand this behaviour. The expected behaviour is to only print >>> followed by a read from stdin. Help me out doing this only using syscalls.

  • Well, you only `read` one character at a time. So every subsequent character you inputted is "triggering" another iteration of the loop (also remember the newline character!). As for the first issue, it is because `printf` is line-buffered by default. – Eugene Sh. Feb 28 '23 at 15:29
  • @EugeneSh you say "by default", so is there any way or flags to disable line-buffering for `printf()`? – user1094822 Feb 28 '23 at 15:49
  • First issue: [*Why does printf not flush after the call unless a newline is in the format string?*](https://stackoverflow.com/q/1716296/2505965) – Oka Feb 28 '23 at 15:56
  • This can all be summarized as: if you wish to ensure a certain order of printing/scanning no matter functions, then use `fflush(stdout);` after each print. – Lundin Feb 28 '23 at 16:04
  • Second issue: Write a nested loop that reads / writes until it reaches some terminating sentinel value (`'\n'`, `'q'`) ([cursory example](https://godbolt.org/z/fq3zMP1oo)). As Eugene says, you current write the prompt and the newline for *every* character read. – Oka Feb 28 '23 at 16:14

0 Answers0