I'm trying to read a line with scanf("%[^\\n]")
; right before it I'm reading an integer with "%d", was told to me that scanf doesn't erase the '\\n' after reading, so I have to call fflush() to avoid it, but even doing that I still have the same problems, so here is my code:
scanf("%d", &n);
fflush(stdin);
lines = (char**)malloc(sizeof(char*)*n);
for(i = 0; i < n; i++){
lines[i] = (char*)malloc(sizeof(char)*1001);
}
for(i = 0;i < n;i++){
scanf("%[^\n]", linhes[i]);
}
I read an integer and then the scanf doesn't wait, it starts reading the input — doesn't matter what the integer value is, whether 5 or 10, the scanf reads all the strings to empty. Already tried with fgets and the result is almost the same, except that it reads some of the strings and skips others.
Let us look at this step by step:
"... read a line with scanf("%[^\\n]");".
scanf("%[^\\n]", buf)
does not read a line. It almost does - sometimes. "%[^\\n]"
directs scanf()
to read any number of non- '\\n'
char
until one is encountered (that '\\n'
is then put back into stdin
) or EOF occurs.
This approach has some problems:
char
is '\\n'
, scanf()
puts it back into stdin
without changing buf
in anyway! buf
is left as is - perhaps uninitialized . scanf()
then returns 0. '\\n'
is read, it is saved into buf
and more char
until a '\\n'
occurs. A '\\0'
is appended to buf
and the '\\n'
is put back into stdin
and scanf()
returns 1. This unlimited-ness can easily overfill buf
. If no char
was saved and EOF
or input error occurs, scanf()
returns EOF
. scanf()
/ fgets()
, etc. functions . If your code does not check it, the state of buf
is unknown. In any case, a '\\n'
is still usually left in stdin
, thus the line was not fully read. This '\\n'
often is an issue for the next input function.
... scanf doesn't erase the '\\n' after reading
Another common misconception. scanf()
reads a '\\n'
, or not, depending on the supplied format. Some formats consume '\\n'
, others do not.
... call fflush() to avoid it
fflush(stdin)
is well defined in some compilers but is not in the C standard. The usual problem is code wants to eliminate any remaining data in stdin
. A common alternative, when the end of the line had not yet occurred, is to read and dispose until '\\n'
is found:
int ch; // Use int
while ((ch = fgetc(stdin)) != '\n' && ch != EOF);
I still have the same problems
The best solution, IMO, is to read a line of user input and then scan it.
char buf[sizeof lines[i]];
if (fgets(buf, sizeof buf, stdin) == NULL) return NoMoreInput();
// If desired, remove a _potential_ trailing \n
buf[strcspn(buf, "\n")] = 0;
strcpy(lines[i], buf);
I recommend that a buffer should be about 2x the size of expected input for typical code. Robust code, not this snippet, would detect if more of the line needs to be read. IMO, such excessively long lines are more often a sign of hackers and not legitimate use.
BLUEPIXY in the comment answered my question:
try
"%[^\\n]"
change to" %[^\\n]"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.