Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
解析CSV文件时遇到的问题_C - Fatal编程技术网

解析CSV文件时遇到的问题

解析CSV文件时遇到的问题,c,C,我尝试将csv文件中的数据解析为“数据”文件中的ID、年龄和GPA字段,但我认为我做得不对(当我尝试打印数据时,打印的是奇怪的数字)。我做错了什么 char data[1000]; FILE *x = fopen("database.csv","rt"); char NAME[300]; int ID[300],AGE[300],GPA[300]; int i,j; i = 0; while(!feof(x)) { fgets(data,999,x); fo

我尝试将csv文件中的数据解析为“数据”文件中的ID、年龄和GPA字段,但我认为我做得不对(当我尝试打印数据时,打印的是奇怪的数字)。我做错了什么

char data[1000];
FILE *x = fopen("database.csv","rt");
char NAME[300];
int ID[300],AGE[300],GPA[300];
int i,j;
i = 0;

while(!feof(x)) {

        fgets(data,999,x);

        for (j = 0; j < 300 && data[i] != ','; j++, i++) {
                ID[j] = data[i];
                i++;
        }

        for (j = 0; j < 300 && data[i] != ','; j++, i++) {
                NAME[j] = data[i];
                i++;
        }

        for (j = 0; j < 300 && ( data[i] != '\0' || data[i] != '\r' || data[i] != data[i] != '\n'); j++, i++) {

                GPA[j] = data[i];

        }

}
char数据[1000];
文件*x=fopen(“database.csv”、“rt”);
字符名[300];
智力识别码[300],年龄[300],平均成绩[300];
int i,j;
i=0;
而(!feof(x)){
fgets(数据,999,x);
对于(j=0;j<300&&data[i]!=',';j++,i++){
ID[j]=数据[i];
i++;
}
对于(j=0;j<300&&data[i]!=',';j++,i++){
名称[j]=数据[i];
i++;
}
对于(j=0;j<300&(数据[i]!='\0'|数据[i]!='\r'|数据[i]!=数据[i]!='\n');j++,i++){
GPA[j]=数据[i];
}
}

首先:对于您正在执行的操作,您可能需要仔细查看函数
strtok
atoi
宏。但是考虑到你发布的代码,这可能还是有点太高级了,所以我要走更长的路

假设这条线是这样的

172924182

然后你需要解析这些数字。数字172实际上是由内存中的两个或四个字节以一种非常不同的格式表示的,字节“0”与数字0完全不同。您将看到的是ASCII码,十进制为48,十六进制为0x30

如果你取一位数字的ASCII值减去48,你会得到一个数字,因为幸运的是数字是按数字顺序存储的,“0”是48,“1”是49,依此类推

但是你仍然有把三位数1 7 2转换成172的问题

所以一旦你有了“数据”: (我添加了注释代码来处理CSV中的未引用、未转义文本字段,因为在您的问题中,您提到了年龄字段,但随后您似乎想使用名称字段。文本字段被引用或转义的情况完全是另一种情况)

size\u t i=0;
整数=0;
INTC;
int字段=0;//字段从0(ID)开始。
//尺寸x=0;
//在发出“中断”之前永不结束的for循环
对于(;;){
c=数据[i++];
//我们刚才读了什么角色?
如果((“,”==c)| |(0x0c==c)| |(0x0a==c)| |(0x00==c)){
//我们已经完成了一个数字字段的读取。它是哪个字段?
开关(现场){
案例0:ID[j]=编号;中断;
案例1:年龄[j]=数量;断裂;
//案例1:NAME[j][x]=0;break;//我们已经读入了NAME,但是我们需要ASCIIZ字符串终止符。
案例2:GPA[j]=数字;中断;
}
//我们在队伍的尽头吗?
如果((0x0a==c)| |(0x0c==c)){
//是的,打破循环,读下一行
打破
}
//读取下一个字段。重新初始化数字。
字段++;
数字=0;
//x=0;//如果我们有另一个文本字段
持续
}
//每次我们得到一个数字时,数字的旧值都会移动一个数量级,然后加上c。这被称为霍纳算法:
//你得到的号码是多少
// 0        "1"     0*10+1 = 1
// 1        "7"     1*10+7 = 17
// 17       "2"     17*10+2 = 172
//172“成品。将172存放在适当的地方。

如果(c>='0'&&c,发布一些示例数据是有帮助的。在
ID
NAME
GPA
中终止字符串不是空的。你没有读入
AGE
。另外(样式说明)所有大写名称传统上都是宏,而不是变量名。还要注意的是。有没有办法只修改一下我的代码来解决这个问题?我觉得feof在这里被错误地使用了,正如Jonathan Leffler指出的那样,这也是一个问题。我担心你需要大量重写代码,我还建议你可以看到,即使是回答这样的问题也有点令人不快。
size_t i   = 0;
int number = 0;
int c;
int field = 0; // Fields start at 0 (ID).
// size_t x = 0;

// A for loop that never ends until we issue a "break"
for(;;) {
    c = data[i++];
    // What character did we just read?
    if ((',' == c) || (0x0c == c) || (0x0a == c) || (0x00 == c)) {
        // We have completed read of a number field. Which field was it?
        switch(field) {
            case 0: ID[j] = number; break;
            case 1: AGE[j] = number; break;
            // case 1: NAME[j][x] = 0; break; // we have already read in NAME, but we need the ASCIIZ string terminator.
            case 2: GPA[j] = number; break;
        }
        // Are we at the end of line?
        if ((0x0a == c) || (0x0c == c)) {
            // Yes, break the cycle and read the next line
            break;
        }
        // Read the next field. Reinitialize number.
        field++;
        number = 0;
        // x = 0; // if we had another text field
        continue;
    }
    // Each time we get a digit, the old value of number is shifted one order of magnitude, and c gets added. This is called Horner's algorithm:
    // Number   Read    You get
    // 0        "1"     0*10+1 = 1
    // 1        "7"     1*10+7 = 17
    // 17       "2"     17*10+2 = 172
    // 172      ","     Finished. Store 172 in the appropriate place.
    if (c >= '0' && c <= '9') {
        number = number * 10 + (c - '0');
    }
    /*
       switch (field) {
           case 1:
               NAME[j][x++] = c; 
               break;
       }
    */
}