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 open a file and read something. But sscanf
is acting strangely. For instance I declare a string called atm
with the content 'ATOM'
. Before the sscanf
it prints this string as ATOM
while after it is null. What could be the problem? I assume it must be an allocation problem but I could not find it. I tried some suggestions on other topics like replacing %s
with other things but it did not help.
void Get (struct protein p, int mode, int type)
{
FILE *fd; //input file
char name[100]="1CMA"; //array for input file name
char string[600]; //the array where each line of the data file is stored when reading
char atm[100]="ATOM";
char begin[4];
int index1 =0;
fd = fopen(name, "r"); // open the input file
if(fd==NULL) {
printf("Error: can't open file.\n");
return 1;
}
if( type==0 ) { //pdb file type
if( mode==0 ) {
while( fgets(string, 600, fd)!=NULL ) {
printf("1 %s\n",atm);
sscanf (string, "%4s", begin );
printf("2 %s \n",atm);
}
}
}
fclose(fd);
free(fd);
free(name);
}
The string
begin
isn't big enough to hold the four characters thatsscanf
will read and its\0
terminator. If the\0
is written intoatm
(depending on where the strings are in memory),atm
would be modified. From the sscanf manpage, about thes
directive: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:
This produces the output:
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 atbegin+16
, reading sixteen characters intobegin
puts a null terminator atbegin+16
, which is the first character ofatm
, so nowatm
has length 0.