将.csv解析为C中的3d数组

时间:2016-02-06 18:11:18

标签: c csv multidimensional-array

我正在尝试编写一个可以置换给定CSV列的程序。我的目标是将CSV解析为3D char数组,转置它,置换它,转置回来,写出文件

我的函数getRows()存在问题。每次我增加到下一行时,似乎第一行被覆盖。我发布了整个事情,因为我不太可能在早期阶段翘起并导致问题(原谅我,如果我做了一些非常愚蠢的事情,我是C的新手)

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

    #define MAXLEN 10

    char*** getRows(FILE *file, char*** rows);
    char*** createArray(int size);    

    /* Fucntion to read a csv and output the rows permuted */
    int main() 
    {
        char*** rows;
        FILE *fp;

        fp = fopen("text.csv", "r");
        if(fp == NULL) 
        {
            printf("Didn't open\n");
            return -1;
        }
        rows = createArray(MAXLEN);
        rows = getRows(fp, rows);
        fclose(fp);

        return 0;
    }

/* Initializes Array */
    char*** createArray(int size)
    {
        char* values = calloc(size*size, sizeof(char));
        char** row;
        char*** rows = malloc(size*sizeof(char**));
        int i, j;
        for (i=0; i<size; ++i)
        {
            row = malloc(size*sizeof(char*));

            for(j=0; j<size; ++j)
            {
                row[j] = values + j*size;
            }

        rows[i] = row;
    }
    return rows;
}

/* Poppulates the array with the file data */
char*** getRows(FILE *file, char*** rows)
{
    int c;
    int i, j, k;

    i = j = k = 0;
    while((c=fgetc(file)) != EOF)
    {
        if (c == ' ');
        else if (c == ',') /*indicate end of entry and move to next entry in row*/
        {
            rows[i][j][k] = '\0'; 
            ++j;
            k = 0;
        }
        else if (c == '\n') /*indicate end of entry, indicate end of row, move to next row*/
        {
            rows[i][j][k] = '\0';
            rows[i][j+1][0] = '\0';
            ++i;
            j = k = 0;
        }
        else /* add char to entry */
        {
            rows[i][j][k] = c;

            /* Debugging */
            printf("%i\t%i\t%i\t", i, j, k);
            putchar(rows[i][j][k]);
            printf("\t");
            putchar(rows[0][0][0]);
            printf("\n");

            ++k;
        }
    }
    rows[i][j][k] = '\0';
    rows[i+1][0][0] = '\0';
    return rows;    
 }

因此调试会记录以下[i, j, k, rows[i][j][k], rows[0][0][0]]

0       0       0       h       h
0       0       1       e       h
0       0       2       a       h
0       0       3       d       h
0       0       4       e       h
0       0       5       r       h
0       0       6       1       h
0       1       0       h       h
0       1       1       e       h
0       1       2       a       h
0       1       3       d       h
0       1       4       e       h
0       1       5       r       h
0       1       6       2       h
0       2       0       h       h
0       2       1       e       h
0       2       2       a       h
0       2       3       d       h
0       2       4       e       h
0       2       5       r       h
0       2       6       3       h
1       0       0       1       1
1       1       0       2       1
1       2       0       3       1
2       0       0       4       4
2       1       0       5       4
2       2       0       6       4
3       0       0       7       7
3       1       0       8       7
3       2       0       9       7

我希望一切都清楚。谢谢你的建议!

1 个答案:

答案 0 :(得分:0)

您的问题出在“创建”中。

rows指向行数组。每行都有列,每列都有一个值(一个值)。

当您将值的地址分配给行的列时,我看到不涉及i。这表示您将values的第一行的地址重复分配给每个row[i][k]

因此,不仅第一行被覆盖,所有行都被覆盖(只有一行值)。

稍后,在getRows我看到您使用rows作为rows[i][j][k]。因此,每个row[i][j]都有size个值。然后有size*size*size个值(您只分配size*size):

char*** createArray(int size)
{
    char* values = calloc(size*size*size, sizeof(char));
    char** row;
    char*** rows = malloc(size*sizeof(char**));
    int i, j;
    for (i=0; i<size; ++i)
    {
        row = malloc(size*sizeof(char*));

        for(j=0; j<size; ++j)
        {
            row[j] = values + i*size*size + j*size;
        }
        rows[i] = row;
    }
    return rows;
}