phoxis phoxis - 1 month ago 11
C Question

scanf: "%[^\n]" skips the 2nd input but " %[^\n]" does not. why?

Consider the following code:

#include <stdio.h>

int main (void)
{
char str1[128], str2[128], str3[128];

printf ("\nEnter str1: ");
scanf ("%[^\n]", str1);
printf ("\nstr1 = %s", str1);

printf ("\nEnter str2: ");
scanf ("%[^\n]", str2);
printf ("\nstr2 = %s", str2);

printf ("\nEnter str3: ");
scanf ("%[^\n]", str3);
printf ("\nstr3 = %s", str3);

printf ("\n");
return 0;
}


When it is executed only the first
scanf
stops for the prompt. The program does not stop for the next
scanf
s. But if the format string is changed from
"%[^\n]"
to
" %[^\n]"
(note the blank space before
%
), then it works okay. Does some existing newline character from the previous input buffer is automatically accepted ? But flushing
stdin
does not solve this.

What is the cause of this.

Answer

You just need to 'consume' the '\n' character after you've read what you want. Use the following format directive:

"%[^\n]%*c"

Which will read everything up to the newline into the string you pass in, then will consume a single character (the newline) without assigning it to anything (that '*' is 'assignment suppression').

Otherwise,the newline is left in the input stream waiting to immediately terminate the the subsequent "%[^\n]" format directives.

The problem with adding a space character to the format directive (" %[^\n]") is that the space will match any white space. So, it will eat the newline from the end of the previous input, but it will also eat any other whitespace (including multiple newlines).

Update to your example:

  char* fmt = "%[^\n]%*c";

  printf ("\nEnter str1: ");
  scanf (fmt, str1);
  printf ("\nstr1 = %s", str1);

  printf ("\nEnter str2: ");
  scanf (fmt, str2);
  printf ("\nstr2 = %s", str2);

  printf ("\nEnter str3: ");
  scanf (fmt, str3);
  printf ("\nstr2 = %s", str3);

  printf ("\n");