将CSV元素导入C中的2D数组 [英] Import CSV elements into a 2D array in C

查看:178
本文介绍了将CSV元素导入C中的2D数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C很新。我一直在尝试从csv文件导入整数元素到C中的数组。当我必须导入具有较少行和列的CSV文件时,代码工作正常;例如,我已经尝试它与一个CSV文件具有90行和80列成功。但是,当CSV具有更多行/列时,问题就开始了。具体来说,我正在尝试导入包含238行和320列的CSV文件。但是程序终止显示导致此程序停止工作的问题。我在代码中提到程序出错了。请帮助我,因为我无法知道这个问题背后的原因。



我在其他地方搜索,但没有找到特定于C的答案。还有一个类似的问题在Stackoverflow这里:(因为,它是一维数组,我的方法有点不同,我已经决定提出一个新的问题在这里。)
将CSV导入C中的数组



以下是CSV文件的特定链接:
https://drive.google.com/file/d/0BxnaWIgBd3AjbGVrY1FTdFpxemM/ edit?usp = sharing



以下是我的代码:

  #include< stdio.h> 
#include< stdlib.h>
#define ARRAYSIZE(x)(sizeof(x)/ sizeof(*(x)))

int main(void)
{
const char filename [ ] =1.csv;
/ *
*打开文件。
* /
FILE * file = fopen(filename,r);
if(文件)
{
int array [320] [238];
size_t i,j,k;
char buffer [BUFSIZ],* ptr;
/ *
*从文件中读取每一行。
* /
for(i = 0; fgets(buffer,sizeof buffer,file); ++ i)
{
/ *
*将每行的分隔值转换为'array'。
* /
for(j = 0,ptr = buffer; j {
array [i] [j] =(int)strtol(ptr,& ptr,10);
}
/ *问题似乎发生在这里...第237次迭代后...
i开始将迭代提前到238,直到
237迭代,使程序挂起.....这个错误永远不会
OCCURS为CSV文件的小尺寸,特别是99行
和79列* /
}

fclose(file);
/ *
*打印'array'中的数据。
* /
for(j = 0; j {
printf(array [%lu]:,(long unsigned)j );
for(k = 0; k {
printf(%4d,array [j] [k]);
}
putchar('\\\
');
}
}
else / * fopen()返回NULL * /
{
perror(filename);
}
return 0;
}

此外,我想强调的是,代码工作得很好对于较小的CSV,如[110] x [90],迭代完全停止在i = 109。然而,对于像这样的更大的数组,i不停止在237.此外,我事先知道确切的行数和列数。这不是分配的问题,它是循环的问题(这导致分段错误)。

解决方案

以添加比数组可容纳的更多行数据。你声明数组为 int array [320] [238]; - 320行,238列。数组是 0 ,意思是数组的元素运行 [0-319] [0-237] code>。这就是为什么多达319可以工作,但在320上失败。尝试增加数组大小,或者只声明数组列,然后根据需要动态分配行。



您的csv文件和以下工作。我还发现你的数据实际上是 238行 x 320列,如额外的答案所示。所以是的,你的数组应该实际上是 array [238] [320] 。动态分配有它的优点:

  #include< stdio.h> 
#include< stdlib.h>

#define ARRAY_WIDTH 320

int main(int argc,char * argv []){

int * array [ARRAY_WIDTH];
int idx = 0;
int j = 0;
char * buffer = NULL;
size_t len = 0;
ssize_t read;
char * ptr = NULL;

FILE * fp;
fp = fopen(test.txt,r); //打开文件,只读
if(!fp){
fprintf(stderr,无法打开读取文件\\\
);
return 1;
}

while((read = getline(& buffer,& len,fp))!= -1){

array [idx] = malloc(sizeof(array));

for(j = 0,ptr = buffer; j array [idx] [j] =(int)strtol(ptr,& ptr, 10);

idx ++;
}

fclose(fp);
int i = 0;

for(i = 0; i< idx; i ++){
printf(\\\
array [%d] [] =,i);

for(j = 0; j< ARRAY_WIDTH; j ++)
printf(%d,array [i] [j]);
}

puts();

return 0;
}

这假定你有一个固定的ARRAY_WIDTH。在你的case 320.注意使用 getline 而不是 fgets ,它是首选的行输入方法。 / p>

I am pretty new to C. I have been trying to import integer elements from a csv file into array in C. The code works fine when I have to import CSV files having lesser rows and columns; for example, I have tried it successfully with a CSV file having 90 rows and 80 columns. However, the problem begins when the CSV has more number of rows/columns. To be specific, I am trying to import a CSV file containing 238 rows and 320 columns. However the program terminates showing "A problem caused this program to stop working". I have mentioned in the code where the program goes wrong. Please help me as I am unable to know the reason behind this problem.

I have searched elsewhere, but did not find answers specific to C. Also, there is a similiar question on Stackoverflow here: (Since, it is for 1D array, and my approach is somewhat different, I have decided to ask a new question here.) CSV into array in C

Here is the specific link for CSV file: https://drive.google.com/file/d/0BxnaWIgBd3AjbGVrY1FTdFpxemM/edit?usp=sharing

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE(x)  (sizeof(x)/sizeof(*(x)))

int main(void)
{
   const char filename[] = "1.csv";
   /*
    * Open the file.
    */
   FILE *file = fopen(filename, "r");
   if ( file )
   {
      int array[320][238];
      size_t i, j, k;
      char buffer[BUFSIZ], *ptr;
      /*
       * Read each line from the file.
       */
      for ( i = 0; fgets(buffer, sizeof buffer, file); ++i )
      {
         /*
          * Parse the comma-separated values from each line into 'array'.
          */
         for ( j = 0, ptr = buffer; j < ARRAYSIZE(*array); ++j, ++ptr )
         {
            array[i][j] = (int)strtol(ptr, &ptr, 10);
         }
         /* The problem seems to occur here..after the 237th iteration...
         "i" begins to advance the iteration to 238 after it has done upto
         237 iterations which is making the program hang.....THIS ERROR NEVER
         OCCURS FOR CSV FILES OF SMALLER DIMENSIONS, SPECIFICALLY SAY 99 rows
         and 79 columns*/
      }

      fclose(file);
      /*
       * Print the data in 'array'.
       */
      for ( j = 0; j < i; ++j )
      {
         printf("array[%lu]: ", (long unsigned)j);
         for ( k = 0; k < ARRAYSIZE(*array); ++k )
         {
            printf("%4d ", array[j][k]);
         }
         putchar('\n');
      }
   }
   else /* fopen() returned NULL */
   {
      perror(filename);
   }
   return 0;
}

Also, I would like to stress upon the fact that the code works perfectly well for smaller CSV's like [110]x[90] and the iteration stops exactly at i=109. However, for bigger arrays like these, "i" is not stopping at 237. Also, I know the exact number of rows and columns beforehand. It's not a problem with allocation, it's the problem with the loop (which is leading to segmentation fault).

解决方案

You are attempting to add more rows of data than your array can hold. You declared the array as int array[320][238]; -- that is 320 rows, by 238 columns. Arrays are 0 based meaning the elements of the array runs [0-319] and [0-237]. That is why up to 319 works, but fails on 320. Try increasing your array size, or just declare the array columns and then dynamically allocate rows as needed.

I tested your csv file and the following works. I also found your data was actually 238 rows x 320 columns as shown in the additional answer. So yes, your array should actually be array[238][320]. Allocating dynamically has its advantages:

#include <stdio.h>
#include <stdlib.h>

#define ARRAY_WIDTH 320

int main (int argc, char *argv[]) {

    int *array[ARRAY_WIDTH];
    int idx = 0;
    int j = 0;
    char *buffer = NULL;
    size_t len = 0;
    ssize_t read;
    char *ptr = NULL;

    FILE *fp;
    fp = fopen ("test.txt", "r");      //open file , read only
    if (!fp) {
        fprintf (stderr, "failed to open file for reading\n");
        return 1;
    }

    while ((read = getline (&buffer, &len, fp)) != -1) {

        array[idx] = malloc (sizeof (array));

        for (j = 0, ptr = buffer; j < ARRAY_WIDTH; j++, ptr++)
            array [idx][j] = (int)strtol(ptr, &ptr, 10);

        idx++;
    }

    fclose (fp);
    int i = 0;

    for (i=0; i<idx; i++) {
        printf ("\narray[%d][] =", i);

        for (j=0; j<ARRAY_WIDTH; j++)
            printf (" %d", array[i][j]);
    }

    puts ("");

    return 0;
}

This presumes you have a fixed ARRAY_WIDTH. In your case 320. Note the use of getline instead of fgets, it is the preferred method of line input.

这篇关于将CSV元素导入C中的2D数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆