【问题标题】:read csv file into 2-d array in c将csv文件读入c中的二维数组
【发布时间】:2015-05-16 00:32:19
【问题描述】:

我对 C 完全不熟悉。我只需要将我的数据输入到一个已经用 C 语言开发的模型中,将数据放入数组中,获取我的输出并将该输出放回我的 Python 程序中。我的数据在一个 CSV 文件中,我只是想把它放在一个二维数组中以运行一些函数。当我运行以下代码以确保我创建了数组时,我在输出中得到一个与原始数据完全不匹配的随机单个值。有时它会打印 0.00000。我正在尝试查看整个数组以确保它已准备好输入。

另外,这只是一个示例;我的真实数据集将有 >3000 行。我知道当我运行我的真实数据时,我需要为此使用malloc(),对吗?

@user3629249 感谢您和 @Cool Guy 为您提供的所有 cmets。这就是我现在所拥有的。我认为 sprintf() 仍然无法将我的数组值转换回浮点数。我已经到处搜索了,但我仍然无法说出我做错了什么,但错误告诉我 data[l][k] 和 todata 仍然不兼容,你能告诉我我是否走在正确的轨道上以及我在做什么sprintf() 函数做错了吗?

#include <stdio.h>

int main() {

FILE *fp;
fp=fopen("airvariablesSend.csv", "r");
if(fp == NULL){
    printf("cannot open file\n\n");
    return -1;
}

// 为简单起见删除了标题。仍然可以在 airvariables.csv 中找到 //column 的含义

float data[9][6]; //for putting into array
int k , l;
float num; //for using getline() function
char *memory;
int nbytes = 500; 

// 使用 malloc 的空间?这是够了还是太多了?

char *token; //for parsing through line using strtok()
char *search = ","; //delimiter for csv 
char *todata; //for

//请求堆空间

memory = (char *) malloc (nbytes + 1);

// 不需要使用 realloc() 因为 getline() 会自动执行? //http://crasseux.com/books/ctutorial/getline.html

for(k = 0; k < 6 ; k++) //repeats for max number of columns
{
    for (l=0; l< 9; l++) //modify for number of rows that you have
    {     
        num = getline (&memory, &nbytes, fp); //reading line by line
        token = strtok(num, search); //separating lines by comma in csv

//显然 strtok() 只会使用空格,我也在这里收到警告。还有逗号分隔的功能吗?

        sprintf(todata, "%f", token);
        data[l][k] = todata;
        printf("%f\n", data[l][k]); 
        }

        }
fclose(fp);
free(memory);



return 0;

    }

【问题讨论】:

  • 哦,对,是的,我试图跳过第一行,因为它们是标题(字符串),但是是的,我将它改回 10,这就是我的想法。我之前在 l
  • 如果文件无法打开,那么代码可能应该退出,而不是继续向下并尝试从文件中读取。注意:stdlib.h 包含 exit() 函数和 EXIT_FAILURE 和 EXIT_SUCCESS 的#defines
  • 在C中,数组偏移量从0开始,最大有效偏移量是数组元素个数-1
  • 发布的代码中有几个“神奇”数字。建议对这些数字使用#define 并使用#define 的名称代替这些幻数
  • 对于一个大数组,把它放在栈上不是一个好主意(就像'data'目前是),而是使用 malloc() 和 realloc() 在堆上获得空间跨度>

标签: c arrays csv output


【解决方案1】:

改变

for (l=1; l< 11; l++)

for (l=0; l< 10; l++)

printf("%f\n", data[10][7]);

printf("%f\n", data[l][k]);

然后将printf 移到后面

data[l][k] = num;

前者是因为数组索引从 0 开始并以长度 1 结束。
完成后者是因为您需要遍历数组以获取存储在数组的每个索引中的每个值并打印它。您不能只使用data[10][7] 并期望打印整个数组。 data[10][7] 是一个无效位置,访问它会调用未定义行为,这意味着任何事情都可能发生,包括分段错误、运行时错误、崩溃等。

此外,如果fopen 未能打开其第一个参数,则在第一个if 的主体末尾添加return -1; 以结束程序的执行。

【讨论】:

    猜你喜欢
    • 2014-09-13
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 2020-05-01
    • 1970-01-01
    相关资源
    最近更新 更多