2017-08-14 110 views
0

我正在研究一个具有读取数据文件的函数的大型项目。但是,在某些测试代码中,该文件不存在,因此在创建时会创建一个空文本文件。我写了下面的代码来弥补这个事件:fscanf读取空文件时崩溃

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做的事情吗?谁能帮我吗?

+1

这些变量像'power_down_type'有什么类型? 'int'? 'INT *'? –

+3

我们如何知道文件能够正确打开?我们如何知道缺少的&&address - 运算符是否正确,并且'struct'包含指针?请发布显示问题的[Minimal,Complete和Verifiable示例](http://stackoverflow.com/help/mcve)。在第二个块中,你有'bootstatus-> power_down_type = 0;'这表明它们是值而不是指针。 –

+0

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; –

回答

1

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

Hard问题,从更INT类型(字符/字节)没有自动浇注

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

这取决于申报,只有int类型声明允许我的样本

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

int tmp1; 

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

    bootstatus->power_down_type = tmp1; 

最新给予严厉的问题(取决于系统,编译器等)

我的答案是基于假设,不能此结构的真实声明,在撰写时刻未知

+2

'时间戳'没问题,它是一个字符串,而不是'// int'作为注释。 –

+0

我改变了答案 –

+1

它被读为'%s',它可能工作,因为指向数组的指针与指向第一个字符的指针相同,但它的用法不正确。 –

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相同的地址。