A well-written program reports invalid input with a comprehensible error message, not with a crash.
Fortunately, it is possible to avoid scanf buffer overflow by either specifying a field width or using the a flag.
When you specify a field width, you need to provide a buffer (using malloc or a similar function) of type char *.You need to make sure that the field width you specify does not exceed the number of bytes allocated to your buffer.
On the other hand, you do not need to allocate a buffer if you specify the a flag character -- scanf will do it for you. Simply pass scanf an pointer to an unallocated variable of type char *, and scanf will allocate however large a buffer the string requires, and return the result in your argument. This is a GNU-only extension to scanf functionality.
Here is a code example that shows first how to safely read a string of fixed maximum length by allocating a buffer and specifying a field width, then how to safely read a string of any length by using the a flag.
int main()
{
int bytes_read;
int nbytes = 100;
char *string1, *string2;
string1 = (char *) malloc (25);
puts ("Please enter a string of 20 characters or fewer.");
scanf ("%20s", string1);
printf ("\nYou typed the following string:\n%s\n\n", string1);
puts ("Now enter a string of any length.");
scanf ("%as", &string2);
printf ("\nYou typed the following string:\n%s\n", string2);
return 0;
}
There are a couple of things to notice about this example program. First, notice that the second argument passed to the first scanf call is string1, not &string1. The scanf function requires pointers as the arguments corresponding to its conversions, but a string variable is already a pointer (of type char *), so you do not need the extra layer of indirection here. However, you do need it for the second call to scanf. We passed it an argument of &string2 rather than string2, because we are using the a flag, which allocates a string variable big enough to contain the characters it read, then returns a pointer to it.