Reputation:
// Some initialization code
dup2(fd[0], fileno(stdin));
// This process is receiving the output of "ls -1"
while (scanf("%[^\n]s", someCharArray) > 0) {
scanf("%*c");
printf("%s\n", someCharArray);
}
This successfully prints all the files. However, the loop never exits. If I take away scanf("%*c")
, it does exit, but only the first filename is printed.
I would expect the consuming of the newline character will prepare the outer scanf
to scan the next filename, which is what it seems to be doing. But after the final filename is scanned, I expect the nested scanf
to not scan anything. Then the outer scanf
to not scan anything either. And the while loop exits.
Why is this happening?
Upvotes: 2
Views: 980
Reputation: 153498
Loop does not exit as it is waiting for more input.
You can
send a pair of \n\n
so scanf("%[^\n]...
returns 0 as it fails to scan the 2nd \n
, or
close stdin
(in an implementation specific way) so scanf()
return EOF
, a negative number.
Better to use fgets()
. @WhozCraig Although it is still unclear under what condition you want the loop to end (other than stdin
closure).
while (fgets(someCharArray, sizeof someCharArray, stdin)) {
// Lop off potential trailing \n if desired
someCharArray[strcspn(someCharArray, "\n")] = '\0';
printf("%s\n", someCharArray);
}
Note: the "s"
in scanf("%[^\n]s", someCharArray)
serves no purpose - drop it. Also this format, without a width, does not limit the maximum number of character scanned in to someCharArray
and should not be used in quality code.
I would expect the consuming of the newline character will prepare the outer scanf to scan the next filename, which is what it seems to be doing.
Yes - that right. The earlier scanf("%[^\n]...
has no limit on the number of characters scanned which could lead to undefined behavior (UB), so why expect the rest of code to behave?
But after the final filename is scanned, I expect the nested scanf to not scan anything.
If the final final filename has a '\n'
after it, scanf("%*c");
will consume it. If the final filename lacks any following character, scanf("%*c");
will patiently wait for a character. If the input stream has been close, it will return EOF
instead of waiting. Code does not report/test the result of scanf("%*c");
so we are left to guess.
Then the outer scanf to not scan anything either. And the while loop exits.
True, if the first character to scan is a '\n'
, it will remain in stdin
and scanf()
will return 0. if stdin
is closed, scanf()
will return the negative number EOF
.
Upvotes: 1