【问题标题】:retrieve column id of csv file [closed]检索 csv 文件的列 ID [关闭]
【发布时间】:2011-02-24 08:07:30
【问题描述】:

我想问是否有任何方法可以使用 C 编程检索 csv 文件的列号?默认情况下在 csv 文件中设置的那些数字以及行名称 i-e :

A B C........ Z AA AB AC............

【问题讨论】:

  • 欢迎来到 C,只要您乐于自己动手,就没有什么能阻止您。
  • 我一定会这样做,但需要一些指导
  • CSV 文件没有列或行 ID。您是指列索引还是行索引(0、1、2 等)?你不能只维护一个计数器吗?
  • 是的,如何检索列索引。实际上我需要这些索引在特定的行和列中插入值谢谢
  • 这似乎是有人试图为我完成他们的家庭作业。

标签: c linux file csv


【解决方案1】:

抱歉,兰迪,但您对此有一些很大的误解。 CSV 文件非常像您在记事本中创建的文本文件,其中单词/值之间恰好有逗号。如果你想在 C 中阅读它们,你可以使用 scanf() 解析每一行 - 或者:

  • 编写一个只能处理一种特定字段布局的程序:如...

    char name[128]; int age; int height_cm; int weight_kg;
    
    while (scanf("%.128[^,],%d,%d,%d", name, &age, &height_cm, &weight_kg) == 4)
    // do something with the values just read...
    
  • 尝试将字段解析为各种类型,直到失败:

    char buffer[128];
    char delimiter;
    int num_fields;
    
    while ((num_fields = scanf("%.128[^,]%c", buffer, delimiter)) >= 1)
    {
    // use e.g. strtod to see if the field might be reasonably interpreted as a double
    ...
    
    if (num_fields == 1 || delimiter != 'c')
        break; // end of line...
    }
    

根据以下评论/问题进行编辑:

抱歉 - 我只是不明白你在问什么。什么是“增加”数据?如果你的意思是文件有不同的行代表不同的行,并且有不止一列,那么是的,这是正常的,它可以通过我上面列出的方法来解析。如果您要问“如何保存行/列以供将来处理”,那么您可以使用字段创建结构(如果您知道要对列名和类型进行硬编码),或者使用数组(也许char 数据最初)。然后,您可以拥有这些结构/数组的数组(或链表,如果您有相应的库)。例如:

static const int Max_Persons = 1000;

struct Person { char name[128]; int age; int height_cm; int weight_kg; };

Person persons[Max_Persons];
int num_persons = 0;  // how many read from CSV file so far?

while (scanf("%.128[^,],%d,%d,%d",
             persons[num_persons].name, &persons[num_persons].age,
             &persons[num_persons].height_cm,
             &persons[num_persons].weight_kg) == 4)
    if (++num_persons == Max_Persons)
    {
        printf("WARNING: can only handle the first %d people, ignoring rest\n",
               Max_Persons);
        break;
    }

这将读取(从标准输入 - 如果您想直接从命名文件读取,请切换到使用 fopen() 和 fscanf())最多 MAX_LINES 个“Person”行。

如果您不知道需要使用我之前列出的替代(更复杂)方法的数据数量和类型:尝试传递每个字段直到失败,检查以逗号结尾的字段与文件结尾。离题且未经测试,例如:

struct Field { char buf[Max_Field_Len]; };
struct Row { Field r[Max_Columns]; };
Data Row[Max_Rows];
int num_columns = 0;
int current_column = 0;
int num_rows = 0;
int num_fields;
char delimiter;
while ((num_fields = scanf("%[^,]%c", Row[num_rows][current_column].buf, &delimiter)) >= 1)
{
    if (++current_column > num_columns)
        num_columns = current_column;
    if (num_fields == 2 && delimiter != ',')
    {
        current_column = 0;
        ++num_rows;
    }
    else if (num_fields == 1)
        break; // end-of-file
}

【讨论】:

  • 托尼先生非常感谢。实际上,在我的程序中,数据将在两个方向上增加,即行和列是他们处理它的一种方式。谢谢
  • @randy:我试图在答案的编辑中添加更多细节。
  • 感谢托尼先生,非常感谢您的帮助和关心。实际上,我在运行时将数据填充到 csv 文件中,数据将不断更新 dnt 具有预定义的字段,即列名和行名。在运行时我必须添加新的列或行,但问题是,例如,我的第 1 行填充了 3 个列然后我移动到第 2 行填充让我们说 2 列但是如何将指向指针再次移动到第 1 行以填充第 4 列谢谢
  • randy:磁盘上的实际 CSV 文件将没有现有空间来插入新列:您必须读取文件的其余部分,然后使用 FILE 流上的 seek 函数返回到指向要插入新列的位置,写入该列值,然后再次写出文件的其余部分。如果您过于专注于该问题,那么您将编写一个不灵活的系统。相反,考虑三个阶段:读取 CSV 文件,在内存中执行多个操作,然后用修改后的数据覆盖 CSV 文件。上面的代码是将当前 CSV 数据存入 mem 的非常基本的方法。
猜你喜欢
  • 2012-11-08
  • 2017-07-07
  • 2013-08-06
  • 2017-01-12
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多