c - fscanf 段错误

标签 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 运行良好。

有什么想法吗?

最佳答案

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

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

改用

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" 消耗前导白色-space but has not non-white-space to save. 代码不检查 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();
}

关于c - fscanf 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27411432/

相关文章:

c - 这个程序用C怎么实现呢?第3.2-3.9部分

获取无符号字符指针长度的正确方法

java - Android SSL JNI结构?

c - 如何正确使用 fscanf 仅将需要的信息存储在数组中?

c - scanf 之后 fgets 不起作用

c++ - 段错误错误 11 C++

c - 错误 : More than one instance of overloaded function "sqrt" matches the argument list. 那是什么?

c - linux下的C语言正常运行时间

c++ - 取消引用的列表迭代器段错误

opengl - glBlitFramebuffer 导致访问冲突