scanf string in c - why can i scan more than the char[] declaration?

后端 未结 4 1384
北荒
北荒 2021-01-16 10:15

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 goin

相关标签:
4条回答
  • 2021-01-16 10:47

    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.

    0 讨论(0)
  • 2021-01-16 10:49

    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

    0 讨论(0)
  • 2021-01-16 10:58

    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 */;
    
    0 讨论(0)
  • 2021-01-16 10:59

    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);
    
    0 讨论(0)
提交回复
热议问题