Search code examples
cscanffgets

scanf AFTER fgets breaks the fgets statement


I've seen various posts of how using scanf before fgets might cause problems. However, it makes no sense to me why adding it AFTER should cause the first statement to break.

This is what I have:

  unsigned char key;
  unsigned char message[100];

  printf(" Please input a message \n  ");
  fgets(message, MAX_BUF, stdin); 
  printf("Your message is:  %s \n", message);


  // Read user input for message
  printf(" Please input a numeric key\n  ");
  scanf("%d", &key);

  printf("Your message is:  %s \n", message);
  printf("strlen(message) = %d \n", strlen(message));

And this is a "trial run":

  Please input a message
   hello
   Your message is: hello

  Please input a numeric key
   123

  Your message is: 
  strlen(message) = 0

Like this, the message variable ends up empty no matter the input. However, if I comment out the line with scanf, everything works (except I can't assign key).

Help!


Solution

  • The %d format specifier to scanf() is a promise that the next argument is the address of a memory buffer that is large enough to hold an int (usually 4 or 8 bytes), but your key is just a 1-byte unsigned char, so scanf() will write 3 (or perhaps 7) bytes past the end, trampling on whatever occupies that memory -- in this case, very likely message. What exactly it writes there will depend on the endianness of your system, but for small inputs (<= 255) on a little-endian system (e.g. x86) its second byte (which will be written to the first byte of message) will be 0, which effectively null-terminates message at zero length.