scanf("%[^\n]",line);

tell me the logic of this scanf statement and why " [^\n] " is used instead of %s ...
and how this statement works...

i know that this statement inputs lines till enter is pressed..

but what is the format of the scanf statements please tell..

jephthah commented: interesting +6

Recommended Answers

All 3 Replies

you found a rather interesting and little-understood tidbit in the scanf() function..

note the string has a space ' ' before the specifier: scanf(" %[^\n]",line); ... this is just as critical as the odd-looking format specifier.

from the IEEE Standard:

A directive composed of one or more white-space characters shall be executed by reading input until no more valid input can be read, or up to the first byte which is not a white-space character, which remains unread.

while the %[^\n] excludes newlines from the list of readable whitespace,... meaning that a newline will flush the input buffer and send all input to the character array.

it's kind of neat.

#include <stdio.h>

int main (void)
{
    char line[200];
    while(1)
    {
        printf("\nenter a string: ");
        fflush(stdout);         // safety flush since no newline in printf above
        scanf(" %[^\n]",line);  // note space character
        printf("you entered >%s<\n",line);
    }
    return 0;
}

you can try alternate builds where you remove either the single space, or the %[\n] and see what happens

i will say that, while it looks pretty cool, it appears that you can't protect buffer overruns, like you can with fgets...

i'll also admit i'm a little fuzzy on how exactly this directive is interpreted.

jephthah> it appears that you can't protect buffer overruns, like you can with fgets...

scanf() accepts width. You can take advantage of it to prevent buffer overruns.

char buffer[10];
scanf("%9[^\n]", buffer); /* read nine chars or until it finds a new line, whichever is first */

Must be aware that scan() doesn't accommodate the last char for the terminator as fgets() does. Thus "read 9" instead of "read 10" like buffer has.

hmm... interesting. so using that pattern in the directive is essentially the same as fgets() with the "stdin" input, except for not accommodating the null character, and dropping the \newline. otherwise, the amount of "safety" is the same.

i'm rethinking my kneejerk reactionary position against scanf().... it's definitely powerful, but still might be a little abstract for beginners.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.