[英]Read from a csv file , separate every line and every field in C
I have a csv file in which I have to separate every line (\\n) and every field (,) in this line.我有一个 csv 文件,我必须在其中分隔该行中的每一行 (\\n) 和每个字段 (,)。 My goal is to create an array of structs.
我的目标是创建一个结构数组。 Every struct in each "box" of the array must contains 4 fields of every line.
数组的每个“盒子”中的每个结构都必须包含每行的 4 个字段。 How can I write it in c?
我怎样才能用c写它? I thought to use fscanf and fgets but I don't know how to use them together because with fgets I want to divide lines while with fscanf i want to divide fields .
我想使用 fscanf 和 fgets 但我不知道如何将它们一起使用,因为使用 fgets 我想分割线而使用 fscanf 我想分割字段。
Final situation :最终情况:
| 0 , noto, 233460, 32209.073312 | 1, piangea, 4741192, 811.. | 2 ,spenti! , .... |
| position 0 in the array | position 1 in the array | position 2 in the array |
records.csv记录.csv
0,noto,233460,32209.073312 0,noto,233460,32209.073312
1,piangea,4741192,81176.622633 1,piangea,4741192,81176.622633
2,spenti!,1014671, 4476.013614 2,senti!,1014671, 4476.013614
3,misericordia,496325,61628.929334 3,悲惨,496325,61628.929334
4,quando,4476757,10838.641053 4、全都、4476757、10838.641053
main.c主文件
#include <stdlib.h>
#include<stdio.h>
#include <string.h>
struct _SortedArray {
int id;
char field1[12];
int field2;
float field3;
};
int main() {
FILE *fd;
int res;
struct _SortedArray files[101];
int n;
fd = fopen("records.csv", "r");
if (fd == NULL) {
perror("Error");
exit(1);
}
char r[100];
n = 0;
while (n<6) {
if(fgets(r,100,fd)!=NULL){
puts(r);
fscanf(r, "%[^,],%[^,],%[^,],%[^\n]\n", &files[n].id, &files[n].field1, &files[n].field2, &files[n].field3);
}
n++;
}
for(int i=0;i<6;i++){
printf(" INT:%c,CHAR:%s //",files[i].id, files[i].field1);
}
return 0;
}
Your code contains various little problems and a major inconsistency.您的代码包含各种小问题和重大不一致。 The major inconsistency is that you should use
sscanf
instead of fscanf
to process the line returned by fgets
.主要的不一致是您应该使用
sscanf
而不是fscanf
来处理fgets
返回的行。
But that is not all:但这还不是全部:
field1
must have at least 13 as sizefield1
大小必须至少为 13&
&
So the line could become:所以这条线可以变成:
sscanf(r, "%d,%[^,],%d,%f", &files[n].id, files[n].field1, &files[n].field2, &files[n].field3)
Other possible improvements:其他可能的改进:
_
should be reserved for those that you do not use._
开头的标识符应保留给您不使用的标识符。 Close to an opinion, but here you should better use SortedArray
SortedArray
sizeof
operator where you can.sizeof
运算符替换大小的普通魔术值。 If you later change a size, you will have to change it in one single place in your code (best practice: Don't Repeat Yourself)[s]scanf
to be robust against erroneous input data[s]scanf
对错误的输入数据具有鲁棒性%12[^,]
)%12[^,]
) The code could become:代码可以变成:
#include <stdlib.h>
#include<stdio.h>
#include <string.h>
struct SortedArray {
int id;
char field1[13];
int field2;
float field3;
};
int main() {
FILE *fd;
// int res;
struct SortedArray files[101];
int n;
fd = fopen("records.csv", "r");
if (fd == NULL) {
perror("Error");
exit(1);
}
char r[100];
for (n=0; n<sizeof(files)/sizeof(files[0]); n++) {
if(fgets(r,sizeof(r),fd)==NULL){
break;
}
char dummy[2]; // to control nothing is left on end of line
//puts(r);
if (4 != sscanf(r, "%d,%12[^,],%d,%f%1s", &files[n].id, files[n].field1, &files[n].field2, &files[n].field3, dummy)) {
perror("Incorrect line");
fprintf(stderr, "Line %d : %s\n", n+1, r);
}
}
for(int i=0;i<n;i++){
printf(" INT:%d,CHAR:%s //",files[i].id, files[i].field1);
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.