简体   繁体   中英

c - fscanf segmentation fault

Really strange problem with fscanf. It seems as if it can't find the file. Heres the code:

char obs_file[255];
FILE *obs_fp;

strcpy(obs_file, "/aber/dap/cetaceans/data/observers_1.txt");

obs_fp = fopen(obs_file, "r");

date_time t;
fscanf(obs_fp, "%d %d %d %d %d %d\n", &t.day, &t.mth, &t.yr, &t.hrs, &t.mns, &t.scs); //This line runs fine
obs_head.obs->time = t;
printf("%d %d %d %d %d %d\n", t.day, t.mth, t.yr, t.hrs, t.mns, t.scs);

while(feof(obs_fp) == 0) {

    char id[5];
    char a[7];
    char b[7];
    location loc;
    double lng = 0.0, lat = 0.0;
    fscanf(obs_fp, "%s %lf %lf", id, &lat, &lng);  //Seg fault here on first run of loop
    loc.lat = lat;
    loc.lng = lng;
    add_obs_node(make_obs_node(id, loc, t));
}

File to be read:

05 11 2014 14 53 00
AB01 52.408 -4.217

It seems like the file pointer has changed somewhere around the while statement, I would understand if I was reading over the end of file, but it fails while there are definitely lines left. Also, I know Im opening the file right, as the first fscanf runs fine.

Any ideas?

Wrong use of feof() and unlimited fscanf("%s"...

feof() reports if EOF occurred due to previous IO, not if it is about to occur.

Use instead

char id[5];
double lng = 0.0, lat = 0.0;
while(fscanf(obs_fp, "%4s%lf%lf", id, &lat, &lng) == 3) {
  loc.lat = lat;
  loc.lng = lng;
  add_obs_node(make_obs_node(id, loc, t));
}

I suspect original code failed on the 2nd iteration. Assume the last data in the file was "AB01 52.408 -4.217\\n" . fscanf(obs_fp, "%s %lf %lf" would scan up to the "\\n" and put "\\n" back into stdin as it is not part of a double . EOF flag is not set. The use of feof() signals no EOF. So fscanf(obs_fp, "%s %lf %lf" happens again, but no data is save in id , as "%s" consume leading white-space but has not non-white-space to save. Code does not check the fscanf() return value (bad), but assumes good data in id , which may be junk. Then add_obs_node() is called with an invalid string id .

Other failure mechanisms could have occurred too - need to see more code.

Bottom line: Check fscanf() results. Limit string input.


Minor: Note that the spaces between "%d %d" are not needed, but OK to have. The final "\\n" is also OK but not needed. It is not simply consuming the following '\\n' , but any and all following white-space.

if (6 != fscanf(obs_fp, "%d%d%d%d%d%d", 
    &t.day, &t.mth, &t.yr, &t.hrs, &t.mns, &t.scs)) {
  Handle_BadData();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM