Question

I have a program where I need to scanf a string, which I know it will be only 2 characters long. (for example: "ex"). what is the proper way to do that?

I was going for:

char myStr[3];
scanf("%s", myStr);

It works just fine, but when I enter a 10-letter word it also works just fine. How come? Does the [3] has no meaning? How should I do this the proper way?

Thanks.

Was it helpful?

Solution 2

It works just fine, but when I enter a 10-letter word it also works just fine.

It only appears to work fine but it's actually undefined behaviour. That is because scanf stores the characters it reads from stdin into the buffer pointed to by myStr. The size of myStr is 3. Therefore, there's space for only 2 characters. One character space is saved for the terminating null byte to mark the end of the string which is added by scanf automatically. When the input string is longer than 2 characters, scanf overruns the buffer accessing memory out of the bound of the array. It is illegal to access memory out of the array bound and invokes undefined behaviour.

The next time, it may very well crash. It's unpredictable and you should always avoid it. To guard against it, you should specify maximum field width for the conversion specifier %s in the format string of scanf. It should be one less than the array size to accommodate the terminating null byte.

 char myStr[3];
 scanf("%2s", myStr);

Better still, I suggest you to use fgets.

char myStr[3];
// read and store at most one less than 
// sizeof(myStr) chars
fgets(myStr, sizeof myStr, stdin);

OTHER TIPS

The proper way to limit the input using scanf() is

if (scanf("%2s", myStr) != 1) /* error */;

But consider using fgets() rather than scanf()

if (fgets(myStr, sizeof myStr, stdin) == NULL) /* error */;

but when I enter a 10-letter word it also works just fine. How come? Does the [3] has no meaning?

I doesn't work fine. See in this example:

#include <stdio.h>

int
main(int argc, char **argv)
{
  char second[5] = "BBBB";
  char myStr[3] = {0};

  scanf("%s", myStr);

  printf("second = %s\n", second);
  printf("myStr  = %s\n", myStr);

  return 0;
}

writing only two characters in myStr is fine:

a.exe
AA
second = BBBB
myStr  = AA

writing more data overrides the near by memory of second:

a.exe
AAAAAAA
second = AAAA
myStr  = AAAAAAA

You need to limit the number of characters scanf reads using something like scanf("%2s", myStr);, 2 is the size of myStr - 1.

You can´t do that.
scanf will do nothing to prevent it, but it can (or, in larger programs, will)
lead to problems later on. Like unexpectly changed variable values, program crashes...

Use fgets

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top