我有一个csv文件,其中的信息部分用","分隔。我想要做的是获取这些信息并将其存储在不同的结构变量中,但我不知道如何制作它以便将信息存储在那里。
这是我的主要文件:
struct items beer [100];
int main(int argc, char **argv) {
char *oneline, *tok;
char envara[512];
char delim [] = ",";
FILE *fp;
int i = 0;
fp = fopen("varor.csv", "r");
printf("ID\n");
while (!feof(fp)) {
if (fp == NULL) {
fprintf(stderr, "File varor.csv could not be opened\n");
exit(-1);
}
fgets(envara, 512, fp);
envara[strlen(envara) -1] = '\0';
printf("En rad; %s\n", envara);
oneline = strdup(envara);
tok = strtok(oneline, delim);
while (tok != NULL) {
printf("%s\n", tok);
tok = strtok(NULL,delim);
}
}
return 0;
}
这是我的结构:
struct items {
int itemnumber;
char name [100];
float price;
float volyme;
char types [100];
char style [100];
char package [20];
char country [20];
char producer [50];
float alcohol_amount;
};
答案 0 :(得分:3)
应使用fgets
逐行读取文件。如果您读取的流位于文件结尾,它将返回空指针。使用feof
是wrong。
尽管将读取行标记为有时候更好的方法,但您也可以使用sscanf
将每行的数据提取到struct items
。为了使我的示例更易于阅读,我已将struct items
更改为:
typedef struct item_t {
char name[20];
float weight;
unsigned long id;
float price;
} Item;
如果您的CSV文件中没有标题行,则可以将其解析为:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ITEM 5
typedef struct item_t {
char name[20];
float weight;
unsigned long id;
float price;
} Item;
int main() {
Item items[MAX_ITEM];
int i = 0, parsedData;
char line[512];
FILE* csvFile = fopen("test.csv", "r");
if(csvFile == NULL) {
perror("Failed to open file.");
exit(EXIT_FAILURE);
}
while(fgets(line, sizeof(line), csvFile) != NULL && i < MAX_ITEM) {
parsedData = sscanf(line, "%20[^,],%f,%lu,%f",
items[i].name, &items[i].weight, &items[i].id, &items[i].price);
if(parsedData == 4)
items[i++].name[19] = '\0';
else
fprintf(stderr, "Format error in line: %s\n", line);
}
fclose(csvFile);
return 0;
}
在我的示例中,第一个值也可以包含空格,格式字符串的%20[^,]
部分表示:读取任何不是逗号字符的内容,最多20个字符。
注意:使用sscanf
函数不安全,它可能在很多方面导致溢出和未定义的行为。因此,您有责任通过格式字符串保持CSV文件的字段可解析,并保持sscanf
函数的参数列表正确。我的示例将跳过当前行,如果它在第一个逗号之前包含超过20个字符,但是例如如果为id
指定的数字太长,则无法阻止整数溢出。要编写更安全的代码,请考虑使用适当的输入检查为每个不同的字段编写自己的转换函数,然后使用例如使用这些函数对行进行标记化以填充struct items
。