Home > Back-end >  scanf in C doesn't fail when formatted text doesn't match
scanf in C doesn't fail when formatted text doesn't match

Time:10-06

I have hard time understanding how scanf in C works. I need the code below to fail with the input 123 foo.

#include <stdio.h>

int main () {
  int i;
  if (scanf ("%d text", &i) != 1) {
      return 1;
  }
  return 0;
}

I found in C refs that scanf correctly returns the number of successfully assigned arguments (there's 1 specifier in my case), so I can see why the condition in the if statement is satisfied (the integer i is correctly assigned). However I can't see how I check whether the rest of the argument is satisfied as well (string text).

CodePudding user response:

Although it is possible to use the %n specifier to determine the number of characters read so far, the problem is that this will not increase the assignment count, which is returned by scanf. Therefore, it is not easy to tell whether scanf actually wrote to the argument corresponding to the %n specifier or whether a matching failure occurred beforehand, causing this argument to remain untouched by scanf.

This problem can be solved by initializing the value of the variable to a value that can be distinguished from a value that scanf would write to it. In the example below, I initialize the variable to the value -1:

#include <stdio.h>

int main( void )
{
    int i;
    int chars_read = -1;

    if (
        scanf( "%d text%n", &i, &chars_read ) != 1
        ||
        chars_read == -1
    )
    {
        printf( "Bad input!\n" );
        return 1;
    }

    printf( "Good input.\n" );
    return 0;
}

In this program, we do not actually need to know the number of characters that were read (which is the primary purpose of the %n specifier). Instead, we are only using the %n specifier to determine whether it was reached or whether a matching failure occurred beforehand.

CodePudding user response:

you need to do this manually.

Example if you want to fail only if user inputs "123 foo"

int main () 
{
  int i;
  char s[100];
  if (scanf ("%d            
  • Related