使用strtok()从文件中读取数据,然后将其存储在struct中时是否为空条目?
我正在为我的CS类做一个项目,所需程序的一部分是将数据从逗号分隔的.txt文件加载到结构数组中。一切似乎都按预期工作,但当我从struct数组打印数据(每个完整条目之间有一行)时,似乎有空条目 文件中的数据格式如下:姓、名、地址、城市、电话\n 我使用fgets()获取字符串中的每个文件,然后将其划分为标记,每个标记都放置在结构的相应位置 另外,我认为变量“j”应该表示我有多少条记录?对不对 这是我的密码:使用strtok()从文件中读取数据,然后将其存储在struct中时是否为空条目?,c,file,struct,text-files,strtok,C,File,Struct,Text Files,Strtok,我正在为我的CS类做一个项目,所需程序的一部分是将数据从逗号分隔的.txt文件加载到结构数组中。一切似乎都按预期工作,但当我从struct数组打印数据(每个完整条目之间有一行)时,似乎有空条目 文件中的数据格式如下:姓、名、地址、城市、电话\n 我使用fgets()获取字符串中的每个文件,然后将其划分为标记,每个标记都放置在结构的相应位置 另外,我认为变量“j”应该表示我有多少条记录?对不对 这是我的密码: #include "project.h" void load(char path[])
#include "project.h"
void load(char path[])
{
FILE * f;
char line[300];
f = fopen(path,"r");
j=0;
if (f != NULL)
{
while(!(feof(f)))
{
fgets(line,300,f);
char *parts;
parts=strtok(line, ",");
int i=0;
while (parts !=NULL)
{
switch (i)
{
case 0:
strcpy(entries[j].last, parts);
break;
case 1:
strcpy(entries[j].first, parts);
break;
case 2:
strcpy(entries[j].address, parts);
break;
case 3:
strcpy(entries[j].city, parts);
break;
case 4:
strcpy(entries[j].phone, parts);
break;
}
parts=strtok(NULL, ",");
i++;
}
j++;
}
fclose(f);
printf("Data has been loaded. Program will return to main menu in 3 seconds.\n");
sortEntries();
}
else
printf("\nERROR! FILE DOES NOT EXIST! The program will return to main menu in 3 seconds.\n");
menu();
}
这是我的打印功能:(可能有错误)
您没有从中读取的行中删除换行符-fgets不会删除它们。因此,您的
部分
字符串的末尾将有一个\n。此\n也将出现在您的手机字符串中。因此,printf将在每行之后打印两个新行,一个来自电话字符串,另一个来自格式字符串。使用strtok(NULL,“,\n”)
修复此问题,并使线路馈线成为终止符
另外,您使用的是feof,这是一种邪恶的用法,因为它只有在您尝试读取一些没有数据的内容之后才会被设置。因此,在读取最后一行之后,不会设置feof,您使用fgets读取另一行(由于没有数据而失败),然后在这个不存在的行上执行strtok操作。最好不要使用feof,并检查fgets的返回值,如下所示:
while (fgets(line, 300, f)!=NULL) {
parts=strtok(line, ",");
....
j++;
}
实际上,使用feof()几乎总是错误的。然而,老师们似乎太喜欢它了,以至于不能把它教给学生;) 你发布的部分乍一看似乎是正确的。但是您没有向我们展示条目的定义-它们是如何定义的?您是否为它们分配了足够的内存?组件(最后一个、第一个,…)是定义为字符数组还是指针?如果是指针,您是否为它们分配空间?调试建议:在每个strcpy
之后添加printf
,以查看程序认为它在复制什么。在循环完成时,在之后添加printf
,查看条目[j]
.Hm中的内容。sortEntries()
做什么?是否有可能会删除您的数据?或者,向我们展示一个输出示例。您正在使用fgets()读取行,该函数不会删除尾随的\n。因此,您的电话号码将包括\n,这意味着您在输出的每一行后面都有一条空行(一条来自电话,\n另一条来自格式字符串)。您可以将其与空记录区分开来-空记录至少应显示终止逗号。请参阅以了解为什么处理一行太多。考虑如果有逗号丢失会发生什么。请注意,strtok()
接受多个相邻分隔符作为单个分隔符;如果数据中可能有空字段,则这不是您想要的。这意味着你的结构可能是不完全初始化的;如果只有两个字段,则不会设置地址
,城市
,电话
。我尝试了这个方法,没有多余的空格,但我仍然得到一行,都是“,,,”。而且,即使j应该是=条目数,它也只打印四行(不管有多少条目数),您是否更改了feof()的内容?而且,您是否确保您的输入文件末尾不包含额外的空行?您的程序看起来还可以,但是如果您在load()的末尾和print()的开头添加一个printf(“j=%d\n”,j)
,以确保变量是它应该的,并且不会在两者之间被修改,这将是有帮助的。是的,我更改了feof()部分。在这两种情况下,它都显示j=4,我不知道为什么?该文件当前有8行。还尝试使用另一个具有其他条目的文件。还有4?在你的程序的其余部分一定发生了一些奇怪的事情,我无法从你发布的内容中解释4。将类似于printf(“i=%d j=%d parts=%d\n”)
的内容放在开关前面,并将输出与预期结果进行比较。另外,将条目的定义添加到您的帖子中,可能有问题。
struct entry {
char last[50];
char first[50];
char address[140];
char city[50];
char phone[15];
};
struct entry entries[1000];
while (fgets(line, 300, f)!=NULL) {
parts=strtok(line, ",");
....
j++;
}