I am having problems reading strings with sscanf
. I have dumbed down the code to focus on the problem. Below is a function in the whole code that is supposed to ope
The string begin
isn't big enough to hold the four characters that sscanf
will read and its \0
terminator. If the \0
is written into atm
(depending on where the strings are in memory), atm
would be modified. From the sscanf manpage, about the s
directive:
s Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null byte ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.
I was able to reproduce this behavior on my machine, though the exact positioning of the strings in memory was a bit different. By printing the addresses of the strings, though, it is easy to figure exactly what's happening. Here's a minimal example:
#include<stdio.h>
int main() {
char begin[2];
char atm[100]="ATOM";
printf("begin: %p\n", begin);
printf("begin+16: %p\n", begin+16);
printf("atom: %p\n", atm);
printf("1 %s\n",atm);
sscanf("AAAABBBBCCCCDDDD", "%16s", begin);
printf("2 %s \n",atm);
return 0;
}
This produces the output:
$ ./a.out
begin: 0x7fffffffe120
begin+16: 0x7fffffffe130
atom: 0x7fffffffe130
1 ATOM
2
I printed the values of the pointers to figure out how big a string it would take to overflow into atm
. Since (on my machine) atom
begins at begin+16
, reading sixteen characters into begin
puts a null terminator at begin+16
, which is the first character of atm
, so now atm
has length 0.