fscanf在读取空文件时崩溃

时间:2017-08-14 17:43:32

标签: c scanf satellite uclinux

我正在处理一个具有读取数据文件功能的大型项目。但是,在某些测试代码中,该文件不存在,因此在创建时,它会创建一个空文本文件。我编写了以下代码来补偿此事件:

typedef struct system_boot_status_s{
  char timestamp[18];
  int power_down_type;
  int power_down_cause;
  int boot_number;
  int antenna_deployed;
  int images_captured;
  int beacon_count;
}system_boot_status_t;

////////////////////////////////

// Read the boot status info into the boot status struct
  ret = fscanf(f, "%s %d %d %d %d %d %d",
  bootstatus->timestamp,
  bootstatus->power_down_type,
  bootstatus->power_down_cause,
  bootstatus->boot_number,
  bootstatus->antenna_deployed,
  bootstatus->images_captured,
  bootstatus->beacon_count);

  if (ret != 7) // if 7 items weren't read
  {
    // Make sure all boot status members are set to 0
    snprintf(bootstatus->timestamp, BOOT_INFO_LEN, "xx-xx-xx-xx-xx-xx");
    bootstatus->power_down_type = 0;
    bootstatus->power_down_cause = 0;
    bootstatus->boot_number = 0;
    bootstatus->antenna_deployed = 0;
    bootstatus->images_captured = 0;
    bootstatus->beacon_count = 0;

    return -1;
  }

我知道fscanf返回它读取的内容的数量,但是当我运行这个程序并且它到达空文件时,我的程序就冻结了。我错过了我应该用EOF做的事吗?谁能帮我吗?

2 个答案:

答案 0 :(得分:1)

fscanf(第三个和下一个)的参数必须是指向适当类型的指针。在最简单的情况下,可以使用& 运算符

硬问题,没有从较短的int类型(字符/字节)

自动转换
ret = fscanf(f, "%s %d %d %d %d %d %d",
  bootstatus->timestamp, // string
  &bootstatus->power_down_type, // int
...
  );

这个DEPENDS on声明,我的样本中只允许int声明

如果没有整数,请使用临时变量。在这个例子中,时间戳是不同类型的整数类型(字节等)

   int tmp1;

    ret = fscanf(f, "%s %d %d %d %d %d %d",
      bootstatus->timestamp,
      &tmp1 ,
    ...
      );

    bootstatus->power_down_type = tmp1;

违反此规则会产生严重问题(取决于系统,编译器等)

我的回答是基于假设,而不是这种结构的真实声明,在写作时未知

答案 1 :(得分:0)

您正在将int(按值)传递给接受变量指针的函数(int*)。

只需简单地传递一个变量地址就不再冻结了。 你可以通过去除&var来获取变量地址。

  ret = fscanf(f, "%s %d %d %d %d %d %d",
  bootstatus->timestamp,
  bootstatus->power_down_type,
  bootstatus->power_down_cause,
  bootstatus->boot_number,
  bootstatus->antenna_deployed,
  bootstatus->images_captured,
  bootstatus->beacon_count);

  ret = fscanf(f, "%s %d %d %d %d %d %d",
  bootstatus->timestamp,
  &bootstatus->power_down_type,
  &bootstatus->power_down_cause,
  &bootstatus->boot_number,
  &bootstatus->antenna_deployed,
  &bootstatus->images_captured,
  &bootstatus->beacon_count);

但不是字符串!尽管&timestamp指向的地址与timestamp相同。