[英]read csv file to its end in c
So I have this code that reads a bunch of lines from a csv document. 因此,我有这段代码可以从csv文档中读取很多行。 I know that initially the document has 16 rows, and that's why I designated
int noRows = 16;
我知道文档最初有16行,这就是为什么我指定
int noRows = 16;
in my main funtion. 在我的主要功能上。
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);
} }
My question is how do I read the file to its end without first knowing how many rows it has? 我的问题是,如何在不知道文件有多少行的情况下读取文件的末尾? I'm thinking of having a specific cell in the file just to save
noRows
between startup and shutdown of console. 我正在考虑在文件中具有特定的单元格,只是为了保存控制台启动和关闭之间的
noRows
。
I tried using char buffer[1000]; while(fgets(buffer, 1000, fp)) {}
我尝试使用
char buffer[1000]; while(fgets(buffer, 1000, fp)) {}
char buffer[1000]; while(fgets(buffer, 1000, fp)) {}
but then it reads the first 8 rows(not sure if it's always exactly 8) as 0,0,0,0,0,0,0,0,0,0. char buffer[1000]; while(fgets(buffer, 1000, fp)) {}
,然后它读取前8行(不确定是否总是8)作为0,0,0,0,0,0,0,0,0,0 。
The answer to your question if just test the return value of fgets 您的问题的答案是否只是测试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
...
But as you were told in comments, there are many other problems in your code: 但是正如您在注释中告诉您的那样,您的代码中还有许多其他问题:
x=1;
x=1;
should be x=0;
x=0;
. countTok = 1;
countTok = 1;
is not wrong, but countTok = 0;
countTok = 0;
would be more idiomatic C fprintf(stderr, ...
to notice an error when opening the file. While not wrong, it gives no indication on the cause of the error. perror
would do... fprintf(stderr, ...
在打开文件时注意到错误。虽然没有错,但它并未指出错误原因perror
可以... you erase last character of oneproduct
without controling it is a newline. 你删除的最后一个字符
oneproduct
没有controling它是一个换行符。 The assumption will be wrong 这个假设是错误的
The idiomatic way is to use strcspn
: 惯用的方法是使用
strcspn
:
oneproduct[strcspn(oneproduct, "\\n")] = '\\0'; // erase an optional end of line
oneproduct
to oneline
. oneproduct
复制到oneline
。 Here again, nothing is wrong, but it is useless because you never use the original line else if
could be replaced with a switch, but this one is mainly a matter of style else if
是否可以用开关代替,但这主要是样式问题 token
at the end of loop. token
。 As it is NULL it is a no-op, but it is was not allocated it should not be freed. If you're using fgets
, you can test if the result of the call is equal to NULL
or not. 如果使用的是
fgets
,则可以测试调用的结果是否等于NULL
。 fgets
signals NULL
on error or EOF
(end-of-file). fgets
在错误或EOF
(文件结束)时发出NULL
信号。
char *fgets(char *line, int maxline, FILE *fp);
. 。
IE: IE:
while (fgets(buffer, MAXLINE, fp) != NULL) {
// Process line here.
}
You can also process the entire file character by character and test if (c == EOF)
. 您还可以逐个字符地处理整个文件,并测试
(c == EOF)
。 There are a couple of ways to do it. 有两种方法可以做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.