scanf("%[^\n]s", inputLineArray);
is incorrect and inappropriate:
- the conversion specifier does not have a trailing
s
, it is just %[^\n]
;
scanf
reads the stream and stores any characters before the newline into inputLineArray
and leaves the newline pending in the stream ;
scanf
should be given the maximum number of characters to store to avoid undefined behavior on long lines: scanf("%999[^\n]", inputLineArray)
;
- you should test the return value of
scanf()
to determine if the conversion was successful. The test while (!feof(stdin))
is pathologically inappropriate: Why is “while ( !feof (file) )” always wrong? ;
- you would then see another problem: this conversion fails on empty lines because there are no characters to store into the destination array, and since
scanf()
leaves the newline pending, the second call fails and all successive ones too.
Note also that it is highly risky to call printf
with user supplied data as a format string. The behavior is undefined if the line contains non trivial format specifications.
Here is a better way to read the file line by line:
#include <stdio.h>
#include <string.h>
...
char inputLineArray[1001];
while (fgets(inputLineArray, sizeof inputLineArray, stdin)) {
buf[strcspn(buf, "\n")] = '\0'; // strip the trailing newline if present
printf("%s\n", inputLineArray);
}
...
Note however that input lines with 1000 bytes or more will be broken into multiple output lines.
scanf()
is not the right tool for your purpose, indeed it is full of quirks and shortcomings, but if you are required to use scanf()
, here is a corrected version:
char inputLineArray[1000];
while (scanf("%c", &inputLineArray[0]) == 1) {
/* one byte was read, check if it is a newline */
if (inputLineArray[0] == '\n') {
/* empty line must be special cased */
inputLineArray[0] = '\0';
} else {
/* set the null terminator in case the next `scanf` fails */
inputLineArray[1] = '\0';
/* attempt to read the rest of the line */
scanf("%998[^\n]", inputLineArray + 1);
/* consume the pending newline, if any */
scanf("%*1[\n]");
}
printf("%s\n", inputLineArray);
}
if (feof(stdin)) {
/* scanf() failed at end of file, OK */
} else {
printf("read error\n");
}
Note that feof()
is not used as scanf("%c", ...)
will return EOF
at end of file, so the while()
loop with stop as expected.
feof()
is only used to distinguish end of file from read error conditions in stream I/O. Most C programs do not need to distinguish between these as read errors can be handled the same way as truncated input files. This function is almost always used incorrectly. In short, you should never use feof()
, nor other error-prone or deprecated functions such as gets()
and strncpy()
. Be also very careful with sprintf()
, strcpy()
, strcat()
...