Why does this scanf line not work? "% [^ \ N] \ n"

I have seen some examples where people give scanf a "%[^\n]\n" format string to read the entire input line by the user. If my understanding is correct, it will read each character until a newline character is reached, and then the newline will be used by scanf (and will not be included in the resulting input).

But I can’t get this to work on my machine. A simple example I tried:

 #include <stdio.h> int main(void) { char input[64]; printf("Enter some input: "); scanf("%[^\n]\n", input); printf("You entered %s\n", input); } 

When I run this, I am prompted to enter input, I type a few characters, I press Enter, and the cursor moves to the beginning of the next line, but the scanf call does not end.

scanf not finished

I can press Enter as many times as I like, and it will never end.

scanf is still not finished

The only ways I found to end the scanf call are:

  • enter \n as the first (and only) character in the prompt
  • enter Ctrl-d as the first (and only) character at the prompt
  • enter any input, one or more \n , zero or more other characters and enter Ctrl-d

I don’t know if it depends on the car, but I’m very curious to know what is going on. I'm on OS X if that’s relevant.

+5
source share
3 answers

According to the documentation for scanf (focus):

The format string consists of space characters (any space character in the format string consumes all available consecutive space characters from input), non-white multibyte characters, except % (each such character in the format string consumes exactly one identical character from the input) and the conversion specification.

Thus, your format string %[^\n]\n will first read (and save) an arbitrary number of non-white characters from the input (because of the %[^\n] ), and then read ( and discard) an arbitrary number of whitespace characters such as spaces, tabs or newlines.

Thus, to force scanf to stop reading input, you either need to enter at least one character without spaces after a newline, or streamline the input stream to the end (for example, by pressing Ctrl + D on Unix-ish).

Instead, for your code to work as you expect, just remove the last \n from the end of the line of your format (as Umamahesh P has already suggested).

Of course, this will leave a new line in the input stream. To get rid of it (if you want to read another line later), you can getc from the stream or just add %*c (which means "read one character and discard it") or even %*1[\n] (read one new line and discard it) to the end of the scanf format line.

Ps. Please note that there are a few more problems in your code. For example, to avoid buffer overflow errors, you really should use %63[^\n] instead of %[^\n] to limit the number of characters that scanf will read into your buffer. (The limit should be one less than the size of your buffer, since scanf will always add a trailing null character.)

In addition, the %[ format specifier always expects at least one matching character and will fail if none of them are available. That way, if you hit Enter immediately without typing anything, your scanf will fail (quietly since you won't check the return value) and leave the input buffer filled with random garbage. To avoid this, you should: a) check the return value of scanf, b) set input[0] = '\0' before calling scanf, or c) preferably both.

Finally, note that if you just want to read line by line input, it is much easier to just use fgets . Yes, you will need to strip the end character of the newline (if any) if you do not want it, but it is still much simpler and safer if you try to use scanf for a job that it is not intended to be:

 #include <stdio.h> #include <string.h> void chomp(char *string) { int len = strlen(string); if (len > 0 && string[len-1] == '\n') string[len-1] = '\0'; } int main(void) { char input[64]; printf("Enter some input: "); fgets(input, sizeof(input), stdin); chomp(input); printf("You entered \"%s\".\n", input); } 
+6
source

Missing characters in format of scanf() have a special meaning:

Space character: the function will read and ignore any whitespace characters that appear before the next non-whitespace character (whitespace characters include spaces, newlines and tabs - see isspace). A single space in the format string checks for any number of whitespace characters extracted from the stream (including none).

Thus, "%[^\n]\n" simply equivalent to "%[^\n] " , telling scanf() ignore all whitespace after %[^\n] . That's why all '\n' ignored until a character is entered without spaces, which happened in your case.

Link: http://www.cplusplus.com/reference/cstdio/scanf/

+3
source

Remove the second character of the string and enough.

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

To answer the original,

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

This should also work if you enter a character without a space after entering. Example:

 Enter some input: lkfjdlfkjdlfjdlfjldj t You entered lkfjdlfkjdlfjdlfjldj 
+1
source

Source: https://habr.com/ru/post/1242487/


All Articles