Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

read() from stdin doesn't ignore newline

I am using the following conditional statement to read from standard input.

if ((n = read(0,buf,sizeof(buf))) != 0)

When inputting data from standard input, generally the user presses enter when done. But read() considers '\n' as input too in which case n = 1 and the conditional doesn't evaluate to false. Is there a way to make the conditional evaluate to false when the user presses enter (without entering anything) on standard input apart from checking the contents of buf. Is there any other function other than read() that I might use for this purpose??

For that matter, what can be a way for read to determine end of input when the input comes from standard input (stdin)?

like image 669
s_itbhu Avatar asked Dec 17 '22 06:12

s_itbhu


1 Answers

You ask:

When inputting data from standard input, generally the user presses enter when done. But read() considers '\n' as input too in which case n = 1 and the conditional doesn't evaluate to false.

The first point is certainly true. The enter key is equivalent to the newline key, so when the user presses enter, the keyboard generates a newline character, and the read() function therefore returns that character. It is crucial that it does do that.

Therefore, your condition is misguided - an empty line will include the newline and therefore the byte count will be one. Indeed, there's only one way to get the read() call to return 0 when the standard input is the keyboard, and that's to type the 'EOF' character - typically control-D on Unix, control-Z on DOS. On Unix, that character is interpreted by the terminal driver as 'send the previous input data to the program even if there is no newline yet'. And if the user has typed nothing else on the line, then the return from read() will be zero. If the input is coming from a file, then after the last data is read, subsequent reads will return 0 bytes.

If the input is coming from a pipe, then after all the data in the pipe is read, the read() call will block until the last file descriptor that can write to the pipe is closed; if that file descriptor is in the current process, then the read() will hang forever, even though the hung process will never be able to write() to the file descriptor - assuming a single-threaded process, of course.

like image 177
Jonathan Leffler Avatar answered Jan 09 '23 21:01

Jonathan Leffler