我有两个文件 .csv ,我需要阅读整个文件,但必须按字段提交。我的意思是, csv 文件是用逗号分隔数据的文件,所以我不能使用 fgets 。
我需要读取所有数据,但我不知道如何跳转到下一行。
这是我到目前为止所做的:
int main()
{
FILE *arq_file;
arq_file = fopen("file.csv", "r");
if(arq_file == NULL){
printf("Not possible to read the file.");
exit(0);
}
while( !feof(arq_file) ){
fscanf(arq_file, "%i %lf", &myStruct[i+1].Field1, &myStruct[i+1].Field2);
}
fclose(arq_file);
return 0;
}
它将进入无限循环,因为它永远不会到达下一行 我怎么能到达我刚看到的那条线下面的线?
更新:文件01示例
1,Alan,123,
2,Alan Harper,321
3,Jose Rendeks,32132
4,Maria da graça,822282
5,Charlie Harper,9999999999
文件02示例
1,320,123
2,444,321
3,250,123,321
3,3,250,373,451
2,126,621
1,120,320
2,453,1230
3,12345,0432,1830
答案 0 :(得分:2)
我认为一个示例比提供提示更好,这是fgets()
+ strtok()
的组合,还有其他功能可以用于示例strchr()
,尽管这更容易因为我只是想指出你正确的方向,所以我就这样做了
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int
main(void)
{
FILE *file;
char buffer[256];
char *pointer;
size_t line;
file = fopen("data.dat", "r");
if (file == NULL)
{
perror("fopen()");
return -1;
}
line = 0;
while ((pointer = fgets(buffer, sizeof(buffer), file)) != NULL)
{
size_t field;
char *token;
field = 0;
while ((token = strtok(pointer, ",")) != NULL)
{
printf("line %zu, field %zu -> %s\n", line, field, token);
field += 1;
pointer = NULL;
}
line += 1;
}
return 0;
}
我认为代码的工作原理非常清楚,我希望你能理解。
答案 1 :(得分:2)
如果相同的代码必须同时处理两个数据文件,那么您就会将字段读入字符串,然后将字符串转换为数字。
从您的描述中不清楚您是否需要在行尾处做一些特殊操作 - 但由于只有一个数据行以逗号结尾,因此您必须允许将字段分隔为逗号或换行符。
坦率地说,你可能在使用getchar()
或同等版本时做得很好;这很简单。
char buffer[4096];
char *bufend = buffer + sizeof(buffer) - 1;
char *curfld = buffer;
int c;
while ((c = getc(arq_file)) != EOF)
{
if (curfld == bufend)
…process overlong field…
else if (c == ',' || c == '\n')
{
*curfld = '\0';
process(buffer);
curfld = buffer;
}
else
*curfld++ = c;
}
if (c == EOF && curfld != buffer)
{
*curfld = '\0';
process(buffer);
}
但是,如果你想使用更高级别的函数,那么你确实想使用fgets()
来读取行(除非你需要担心不正常的行结尾,例如DOS vs Unix vs old-style Mac (仅限CR)行结尾)。或者使用POSIX
getline()
读取任意长行。然后使用strtok_r()
或等效的分割线。
char *buffer = 0;
size_t buflen = 0;
while (getline(&buffer, &buflen, arq_file) != -1)
{
char *posn = buffer;
char *epos;
char *token;
while ((token = strtok_r(posn, ",\n", &epos)) != 0)
{
process(token);
posn = 0;
}
/* Do anything special for end of line */
}
free(buffer);
如果您认为必须使用scanf()
,则需要使用以下内容:
char buffer[4096];
char c;
while (fscanf(arq_file, "%4095[^,\n]%c", buffer, &c) == 2)
process(buffer);
%4095[^,\n]
扫描集最多可读取4095个字符,既不是逗号也不是换行符buffer
,然后读取下一个字符(因此必须是逗号或换行符 - 或者可以想象为EOF ,但这导致问题)进入c
。如果文件中的最后一个字符既不是逗号也不是换行符,那么您将跳过最后一个字段。