使用fgets和strtok在C中读取CSV文件仅读取第一列

hkj447

我有一个.csv文件,看起来像

Config,Prob,MAN,ATL,CVERT,TVERT,LVERT,PELV,SAC,RIB,SCAP,PHUM,DHUM,PRAD,DRAD,CARP,PMC,DMC,PHX,PFEM,DFEM,PTIB,DTIB,TARS,PMT,DMT
LH,1,2,2,7,13,6,2,1,13,2,2,2,1,1,6,2,2,24,2,2,2,2,8,2,2
LH,1,0,0,0,0,0,0,0,9,1,2,2,2,2,12,2,2,18,1,1,1,1,4,1,1
LH,1,2,2,7,3,0,2,1,3,1,1,1,1,1,6,1,1,6,0,0,0,0,0,0,0
LH,1,0,0,0,13,6,2,1,8,0,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0
LH,1,2,2,4,13,6,2,1,18,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0
LH,1,0,0,0,13,6,2,1,18,2,2,2,0,0,0,0,0,0,2,2,0,0,0,0,0
LH,3,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
LH,1,0,0,0,13,6,2,1,24,2,2,2,2,2,12,2,2,24,2,2,2,2,8,2,2
LH,1,0,0,1,13,3,2,1,15,2,0,0,2,2,0,0,0,6,2,2,2,2,0,0,0
LH,1,0,0,0,0,0,0,0,10,0,1,1,0,0,0,0,0,18,0,0,0,0,0,0,0
LH,1,0,2,7,3,0,0,0,7,2,2,2,2,2,12,2,2,24,2,2,2,2,8,2,2
LH,1,0,0,2,0,0,0,0,14,1,2,2,2,2,0,0,0,18,2,2,2,2,0,0,0
LK,1,0,0,0,0,0,0,0,13,0,0,0,1,1,6,0,0,0,0,0,0,0,0,0,0
LK,1,2,2,7,13,6,2,1,17,1,0,0,0,0,0,0,0,6,1,1,1,1,4,1,1
LK,1,0,0,0,10,6,0,0,23,1,1,1,1,1,6,1,1,18,2,2,2,2,8,2,2
LK,1,2,2,7,0,0,0,0,18,2,0,0,1,1,12,2,2,24,2,2,2,2,8,2,2
LK,1,0,0,3,0,0,0,0,8,0,0,0,2,2,12,2,2,24,2,2,2,2,8,2,2
LK,1,2,2,7,0,0,0,0,8,0,0,0,2,2,12,2,2,24,0,0,2,2,8,2,2
LK,3,2,2,7,13,6,2,1,22,2,2,2,2,2,12,2,2,24,2,2,2,2,8,2,2
LK,1,2,2,7,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
LK,1,2,2,6,0,3,0,0,11,0,2,2,0,0,12,2,2,18,0,0,0,0,8,2,2
LK,1,2,2,7,13,6,2,1,16,2,1,1,2,2,12,2,2,6,2,2,2,2,8,2,2
LK,1,2,0,0,10,6,2,1,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
LK,1,2,2,5,13,6,2,1,12,1,0,0,0,0,12,2,2,6,0,0,0,0,8,2,2

我想忽略文本,而只抓住数字。这是我的代码:

    int arr[rows][columns]; /* rows/columns of .csv file */
    char buf[1000];
    int r = 0;

    while (fgets(buf,1000,ifp)) {
        char read = 'N';
        const char *tok;
        int ret =0;
        int c = 0;
        int count = 0;
        char *ptr;
        printf("%s \n", buf);

        for (tok = strtok(buf, ","); tok && *tok; tok = strtok(NULL, ",\n")){
                printf("%s ", buf); /* replace buf with tok */
                if(isNumber(tok)==1){
                    read = 'Y';
                    ret = strtol(tok,&ptr,10);
                    arr[r][c] = ret;
                    c++;
                    printf("Entered ");
                    //printf("%ld ", arr[r][c]);
                }
                if(strtok(NULL,"\n") && read == 'N')
                    count++;
        }
        r++;
        //r -= count;
    }

isNumber本质上是isdigt预期的扩展和工作。但是,无论何时打印tok每次迭代,它都会在第一个逗号之后停止。样本输出:Config LH LH LH LH LH LH LH LH LH LH LH LH LK LK LK LK LK LK LK LK LK LK LK LK似乎可以很好地读取输入内容fgets,因为它会打印出.csv文件的每一行。所以看来问题出在我的for循环上。看来我不正确地增加了令牌。

尝试另一个示例:

    char alph[] = "a-b-c-e";
    for (const char *tok = strtok(alph, "-"); tok && *tok; tok = strtok(NULL, "-\0")){
        printf("%s ", tok);
    }

yields:,a b c e这是正确的结果。因此,我感觉我在解析文件时缺少某些东西。任何帮助表示赞赏。谢谢。

乔纳森·莱夫勒

您的循环是:

 for (tok = strtok(buf, ","); tok && *tok; tok = strtok(NULL, ",\n")) 
 {
     …omitted…
     if (strtok(NULL, "\n") && read == 'N')
         count++;
 }

您有3个呼叫strtok(),而其中1个呼叫if占用了换行符的所有内容。我不确定您在想什么。看来您应该忽略这一点strtok()-但我不确定您需要用什么替换它。

由于循环控件中的第二个调用读取的是换行符或逗号(strtok(NULL, ",\n")),因此您无法确定何时到达行尾,除非将tok其设置NULL为表示不再标记。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用Pandas读取不包含标题的CSV文件,仅捕获第一列中的数据并执行删除操作?

在 C 中使用 fgets 和 strtok 读取文件并将信息保存在喜欢的列表中

读取csv文件Python时跳过第一列

我可以读取使用第一列和该列作为微调器输入的 CSV 文件而不重复吗?

CSV.foreach不读取CSV文件中的第一列

在python中读取CSV的第一列

python pandas不从csv文件中读取第一列

读取R中.sav文件的第一列

使用RODBC仅读取Excel文件的一列

熊猫没有适当的分隔符即可读取.csv文件。(仅第一列与“其余”分开)

使用python覆盖csv文件中的第一列和最后一列

C:使用fgets()从文件中读取

使用python在csv文件中仅保留第一列

PHP数组-从CSV文件读取,创建第一列键,第二列值

仅读取CSV文件中的特定列

CSV读取后熊猫掉落第一列

熊猫从csv读取时仅返回一列

读取 csv 文件的列,并使用 Python 将每一列保存在一个变量中

如何从csv中读取第一列并分成多维数组

从csv中读取后,第一列名称用双引号圈出

为什么我的代码只读取Java中.txt文件中数字的第一列

使用 getline 函数读取文件,但第一列显示为空

在 R 中读取 csv 文件并从最后一列中创建一个列表

从数据框中仅读取一列

从csv文件中读取行的每一列数据并根据列索引应用公式

使用第一列中的名称和第二列中的链接保存 .csv 文件(IndentationError:应为缩进块)

仅读取json文件中的第一项

获取xlsx工作表的第一行和第一列,而无需读取R中的全部数据

如果所有值都在同一列中,如何从 csv 文件中读取数据?