[英]read csv file to its end in c
因此,我有这段代码可以从csv文档中读取很多行。 我知道文档最初有16行,这就是为什么我指定int noRows = 16;
在我的主要功能上。
void readBeer(int noRows) {
char *oneline, *token;
char oneproduct[256];
char delim[] = ",";
int x = 1;
FILE *fp; //open file
if ((fp = fopen("varor.csv", "r")) == NULL) //can the file be opened?
{
fprintf(stderr, "File varor.csv couldn't be opened\n"); //"couldn't open file"
exit(-1);
}
while(noRows != 0)
{
int countTok = 1;
fgets(oneproduct, 256, fp); //get the first row
oneproduct[strlen(oneproduct) - 1] = '\0'; // remove end-of-line character
oneline = strdup(oneproduct); //duplicate oneproduct into oneline because strtok modifies the given string
token = strtok(oneline, delim); //split oneline into tokens, tokens are separated by ","
while (token != NULL)
{
if(countTok == 1) beer[x].productNumber = atoi(token);
else if(countTok == 2) strcpy(beer[x].name, token);
else if(countTok == 3) beer[x].price = atof(token);
else if(countTok == 4) beer[x].volume = atof(token);
else if(countTok == 5) strcpy(beer[x].type, token);
else if(countTok == 6) strcpy(beer[x].style, token);
else if(countTok == 7) strcpy(beer[x].packaging, token);
else if(countTok == 8) strcpy(beer[x].country, token);
else if(countTok == 9) strcpy(beer[x].manufacturer, token);
else if(countTok == 10) beer[x].alcohol = atof(token);
else printf("kossan hoppade!"); //should never be seen in console
token = strtok(NULL, delim);
countTok++;
}
x++;
noRows--;
free(oneline); free(token);
}
fclose(fp);
}
我的问题是,如何在不知道文件有多少行的情况下读取文件的末尾? 我正在考虑在文件中具有特定的单元格,只是为了保存控制台启动和关闭之间的noRows
。
我尝试使用char buffer[1000]; while(fgets(buffer, 1000, fp)) {}
char buffer[1000]; while(fgets(buffer, 1000, fp)) {}
,然后它读取前8行(不确定是否总是8)作为0,0,0,0,0,0,0,0,0,0 。
您的问题的答案是否只是测试fgets的返回值
for (;;) // idiomatic C style for an infinite loop
{
int countTok = 1;
if (NULL == fgets(oneproduct, 256, fp)) break; //get one row and exit loop on EOF
...
但是正如您在注释中告诉您的那样,您的代码中还有许多其他问题:
x=1;
应该是x=0;
。 由于相同的原因, countTok = 1;
没错,但是countTok = 0;
会更惯用C fprintf(stderr, ...
在打开文件时注意到错误。虽然没有错,但它并未指出错误原因perror
可以... 你删除的最后一个字符oneproduct
没有controling它是一个换行符。 这个假设是错误的
惯用的方法是使用strcspn
:
oneproduct[strcspn(oneproduct, "\\n")] = '\\0'; // erase an optional end of line
oneproduct
复制到oneline
。 同样,这没什么错,但是这没用,因为您永远不会使用原始行 else if
是否可以用开关代替,但这主要是样式问题 token
。 因为它为NULL,所以它是一个空操作,但未分配它,因此不应释放它。 如果使用的是fgets
,则可以测试调用的结果是否等于NULL
。 fgets
在错误或EOF
(文件结束)时发出NULL
信号。
char *fgets(char *line, int maxline, FILE *fp);
。
IE:
while (fgets(buffer, MAXLINE, fp) != NULL) {
// Process line here.
}
您还可以逐个字符地处理整个文件,并测试(c == EOF)
。 有两种方法可以做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.