brunoais brunoais - 2 months ago 19
C Question

How to read from input until newline is found using scanf()?

I was asked to do a work in C when I'm supposed to read from input until there's a space and then until the user presses enter.
If I do this:

scanf("%2000s %2000s", a, b);


It will follow the 1st rule but not the 2nd.

If I write:

I am smart


What I get is equivalent to:

a = "I";

b = "am";

But It should be:

a = "I";

b = "am smart";


I already tried:

scanf("%2000s %2000[^\n]\n", a, b);


and

scanf("%2000s %2000[^\0]\0", a, b);


In the 1st one, it waits for the user to press Ctrl+D (to send EOF) and that's not what I want.
In the 2nd one, it won't compile. According to the compiler:


warning: no closing ‘]’ for ‘%[’ format


Any good way to solve this?

Answer

scanf (and cousins) have one slightly strange characteristic: any white space in the format string (outside of a scanset) matches an arbitrary amount of white space in the input. As it happens, at least in the default "C" locale, a new-line is classified as white space.

This means the trailing '\n' is trying to match not only a new-line, but any succeeding white-space as well. It won't be considered matched until you signal the end of the input, or else enter some non-white space character.

To deal with this, you typically want to do something like this:

scanf("%2000s %2000[^\n]%c", a, b, c);

if (c=='\n')
    // we read the whole line
else
    // the rest of the line was more than 2000 characters long. `c` contains a 
    // character from the input, and there's potentially more after that as well.
Comments