Disadvantages of scanf

前端 未结 9 1266
傲寒
傲寒 2020-11-22 00:34

I want to know the disadvantages of scanf().

In many sites, I have read that using scanf might cause buffer overflows. What is the reason f

9条回答
  •  春和景丽
    2020-11-22 01:02

    It is very hard to get scanf to do the thing you want. Sure, you can, but things like scanf("%s", buf); are as dangerous as gets(buf);, as everyone has said.

    As an example, what paxdiablo is doing in his function to read can be done with something like:

    scanf("%10[^\n]%*[^\n]", buf));
    getchar();
    

    The above will read a line, store the first 10 non-newline characters in buf, and then discard everything till (and including) a newline. So, paxdiablo's function could be written using scanf the following way:

    #include 
    
    enum read_status {
        OK,
        NO_INPUT,
        TOO_LONG
    };
    
    static int get_line(const char *prompt, char *buf, size_t sz)
    {
        char fmt[40];
        int i;
        int nscanned;
    
        printf("%s", prompt);
        fflush(stdout);
    
        sprintf(fmt, "%%%zu[^\n]%%*[^\n]%%n", sz-1);
        /* read at most sz-1 characters on, discarding the rest */
        i = scanf(fmt, buf, &nscanned);
        if (i > 0) {
            getchar();
            if (nscanned >= sz) {
                return TOO_LONG;
            } else {
                return OK;
            }
        } else {
            return NO_INPUT;
        }
    }
    
    int main(void)
    {
        char buf[10+1];
        int rc;
    
        while ((rc = get_line("Enter string> ", buf, sizeof buf)) != NO_INPUT) {
            if (rc == TOO_LONG) {
                printf("Input too long: ");
            }
            printf("->%s<-\n", buf);
        }
        return 0;
    }
    

    One of the other problems with scanf is its behavior in case of overflow. For example, when reading an int:

    int i;
    scanf("%d", &i);
    

    the above cannot be used safely in case of an overflow. Even for the first case, reading a string is much more simpler to do with fgets rather than with scanf.

提交回复
热议问题