How to read input in C

I am trying to read a line from scanf("%[^\n]")

; right before that I read an integer with "% d", I was told that scanf does not erase "\ n" after reading, so I need to call fflush () to avoid it, but even doing this 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 scanf didn't wait, it starts reading the input - it doesn't matter what the integer value is, no matter 5 or 10, scanf reads all lines to empty. Already tried with fgets and the result is pretty much the same except that it reads some lines and skips others.

+3


source to share


2 answers


Let's take a look at this step by step:

"... read the line with scanf ("% [^ \ n] ");".

scanf("%[^\n]", buf)

does not read the line. It is almost always - sometimes. "%[^\n]"

directs scanf()

to read any number '\n'

char

until it is encountered (which '\n'

then goes back to stdin

) or an EOF occurs.

This approach has some problems:

  • If the first char

    is equal '\n'

    , scanf()

    puts it back in stdin

    , without changing it buf

    in any way! buf

    remains as is - possibly uninitialized . scanf()

    then returns 0.
  • If at least one is not read '\n'

    , it is stored in buf

    or more char

    until it happens '\n'

    . A is '\0'

    added to buf

    , and '\n'

    returned back to stdin

    , and scanf()

    returns 1. This unlimited number can easily overflow buf

    . If not saved char

    and EOF

    or input error, scanf()

    returns EOF

    .
  • Always check the return value scanf()

    / fgets()

    etc. functions
    . If your code does not validate it, the state is buf

    unknown.

In any case, a '\n'

still remains in stdin

, so the line was not fully read. This is '\n'

often a problem for the next input function.

... scanf does not remove '\ n' after reading

Another common misconception. scanf()

reads a '\n'

, or not, depending on the supplied format. Some formats are consuming '\n'

, others are not.



... call fflush () to avoid this

fflush(stdin)

is well defined in some compilers, but not in the C standard. A common problem is that the code wants to delete any leftover data in the stdin

. A common alternative, when the end of the line hasn't been there yet, is to read and delete until found '\n'

:

int ch;  // Use int
while ((ch = fgetc(stdin)) != '\n' && ch != EOF);

      

I still have the same problems

The best solution, IMO, is to read the user's input line 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 the buffer be about 2x the size of expected input for typical code. The reliable code, not this snippet, will determine whether more line needs to be read. IMO, such excessively long lines are most often a sign of hackers and not legitimate use.

+2


source


BLUEPIXY in a comment answered my question:



try "%[^\n]"

changing to" %[^\n]"

0


source







All Articles