Search code examples
cprintfscanf

are printf and scanf used safely here in this code?


#include <stdio.h>

int main() {
    char a[12];

    int b = scanf("%11s", a);

    if (b != 1) { return 1; };

    if (printf("%s", a) > 11) {
       
        return 1;
    };

    return 0;
}

1 - are scanf and printf here used safely ?

2 - am i missing some checks ? i wanna make 100% bug free code in c

3 - is the only issue in scanf buffer overflow ? is it fixed in the above code ?

the purpose of all this is to make a c 100% safe code


Solution

  • Yes, both the scanf() and printf() calls are used safely here. I wouldn't bother checking the return value from printf() but it seems to be a requirement for you. Do use macros, though, to avoid hard-coding the two related array size and maximum field width. As you don't use the variable b for anything I would go with a point free style and eliminate it:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define LEN 11
    #define str(s) str2(s)
    #define str2(s) #s
    
    int main() {
        char a[LEN+1];
        if (scanf("%" str(LEN) "s", a) != 1)
            return EXIT_FAILURE;
        if (printf("%s", a) > 11)
            return EXIT_FAILURE;
    }
    

    Instead of scanf() you could also use getdelim(), getline() or fgets() to avoid the macro noise with sizeof a . Note that scanf("%s", ...) reads a sequence of non-white-space characters (i.e. a word) while getdelim() read a string with a user-specified delimiter and getline() and fgets() read a line. In either case you have to handle the delimiter:

    #include <string.h>
    
       // ...
    
       char a[13];
       if(!fgets(a, sizeof a, stdin))
          return EXIT_FAILURE;
       a[strcspn(a, "\n")] = '\0';
    

    stdout is probably line buffered so it's a good idea to print a trailing newline. a may or may not have a newline so you either have to optional remove it like above and then unconditionally add a newline, say, in the format string, or ensure a contains a newline.