c - fscanf分段故障

时间:2014-12-10 21:45:51

标签: c segmentation-fault scanf

fscanf真的很奇怪。似乎它无法找到该文件。下面是代码:

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));
}

要阅读的文件:

05 11 2014 14 53 00
AB01 52.408 -4.217

似乎文件指针在while语句周围的某处发生了变化,我会理解我是否正在读取文件末尾,但是当有明确的行时它会失败。此外,我知道我正确打开文件,因为第一个fscanf正常运行。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

错误使用feof()和无限fscanf("%s"...

feof()报告是否由于之前的IO而发生EOF,而不是即将发生。

改为使用

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));
}

我怀疑第二次迭代时原始代码失败了。假设文件中的最后一个数据是"AB01 52.408 -4.217\n"fscanf(obs_fp, "%s %lf %lf"会向上扫描"\n"并将"\n"放回stdin,因为它不属于double。未设置EOF标志。使用feof()表示没有EOF。因此fscanf(obs_fp, "%s %lf %lf"再次发生,但id中没有数据保存,因为"%s"占用了领先的空白区域,但没有非空白区域可供保存。代码不检查fscanf()返回值(坏),但假设id中的数据很好,可能是垃圾。然后使用无效字符串add_obs_node()调用id

其他失败机制也可能发生 - 需要查看更多代码。

底线:检查fscanf()结果。限制字符串输入。


轻微:请注意,"%d %d"之间的空格不是必需的,但可以。最终"\n"也可以但不需要。它并不是简单地使用以下'\n',而是使用以下所有空格。

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();
}