2016-07-30 63 views
1

我有类似下面的数据格式:的fscanf格式说明进入结构

22/March/2014 
137 8 
15 16 34 8 18 
17/November/2014 
106 8 
22 29 30 9 6 
20/November/2014 
169 10 
50 58 38 29 1 

我想使用的fscanf来获取文件的内容,并将它们放到下面的结构:

struct date{ 

    //This is storing the date dd/month/yyyy. 
    char* fullDate; 

    // Number of foot and wheelchair passengers. 
    int foot; 
    int wheelchair; 

    //number of infant, child, adult, senior and family tickets sold 
    int infant; 
    int child; 
    int adult; 
    int senior; 
    int family; 
}; 

所以我尝试以下操作:

struct date r[50]; 
    FILE* der = fopen("C:\\Users\\Def\\Downloads\\annual_sales_data_2014.txt","r"); 
    int i = 0; 
    rewind(der); 
    fscanf(der, "%s", r[i].fullDate); 
    fscanf(der, "%d %d ", &r[i].foot, &r[i].wheelchair); 
    fscanf(der, "%d %d %d %d",&r[i].infant, &r[i].child, &r[i].adult, &r[i].senior, &r[i].family); 
    printf("%s\n%d %d\n%d %d %d %d %d\n\n", r[i].fullDate, r[i].foot, r[i].wheelchair, r[i].infant, r[i].child, r[i].adult, r[i].senior, r[i].family); 

    fclose(der); 

但我相信的fscanf没有被正确的使用,我得到一个有点格式说明符的文档困惑,我也尝试过这种方式。

fscanf(der, "%s/%s/%s\n%d %d\n%d %d %d %d %d\n", r[i].day, r[i].month, , r[i].year, &r[i].foot, &r[i].wheelchair, &r[i].infant, &r[i].child, &r[i].adult, &r[i].senior, &r[i].family); 

在上面的例子中,我还照顾了结构接受3个字符*的日月和年。在格式说明符字符串的开头。这不起作用,所以我把它分解为一个更小的格式,看看我能否诊断问题。

即使在细分例如,这

fscanf(der, "%s", r[i].fullDate); 

即使这打破了调试器和无法工作的原因。

谢谢。

+0

当'fscanf'到一个变量,你应该给它是地址。 –

+0

'r [i] .fullDate'没有指向一个能够接收数据的确定的内存缓冲区,但是您将其未定义值作为福音传递给'fscanf'来作为群体。您的代码调用未定义的行为。 – WhozCraig

+0

在第一次尝试中,最后一个'scanf()'需要多一个'%d'。否则,它应该工作,除了需要为每个结构的fullDate成员分配内存(并且应该为'%s'添加适当的宽度以防止溢出)。 – Dmitri

回答

1

由于fulldate是未初始化的指针,因此无法使用fscanf(der, "%s", r[i].fullDate);解析日期。您应该通过%s格式的数组地址。把在该结构的代替一个指针数组,如char fullDate[30];和使用fscanf(der, "%29s", r[i].fullDate);

请注意,可以直接解析日期组件:

char monthName[16]; 
int day, year; 

if (fscanf("%d/%15[^ /]/%d", &day, monthName, &year) == 3) { 
    /* Date parsed correctly */ 
} else { 
    /* At least one field missing, bail out */ 
    exit(1); 
} 
+0

谢谢大家的回复,他们都很欣赏:)这家伙撞在头上,甚至回答了我本来要问但忘记的问题:D。现在我知道如何解析日期,谢谢:) – Definity

1

fullDate必须在使用前初始化。最简单的方法是:

r[i].fullDate = malloc(whatever_size_you_need); 

,或者你甚至可能宣布它作为一个数组,以避免额外的初始化:

struct date{ 

    //This is storing the date dd/month/yyyy. 
    char fullDate[proper_size]; 

    // ... 
}; 

当然,你必须确保在某种程度上是读字符串将放入缓冲区。

0

你说你认为fscanf没有被正确使用,那是真的。此行

fscanf(der, "%d %d %d %d", &r[i].infant, &r[i].child, &r[i].adult, &r[i].senior, &r[i].family); 

正在为要填写的5个字段传递参数,但它只有4个格式的格式说明符。试试这个:

fscanf(der, "%d %d %d %d %d", &r[i].infant, &r[i].child, &r[i].adult, &r[i].senior, &r[i].family); 

此外,你应该总是检查数据字段被正确读取。来自fscanf的返回值会告诉您只有4个项目被读取。