阅读.csv文件的一些code坠毁 [英] Some code of reading .csv file crashed

查看:148
本文介绍了阅读.csv文件的一些code坠毁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个code读取csv文件,并通过获取的行和列更改一个值。在我第一次读文件,检查多少行和COLS那里,比我创建一个动态的2D基于阵列的每一行是该文件的行。实际上使在二维数组文件。比我会改变所选择的线和col的值和整个阵列写回该文件。有人知道为什么它的崩溃?它坠毁在第一线 -


  

bigArr [I] [J] =(char)的CH;


功能:

  INT changeValue(INT线,诠释关口,焦炭海峡[],为const char *路径)
{
    FILE * csvFile = FOPEN(路径,R);
    烧焦常用3 [VERY_BIG_MEMORY]
    INT L = 0,C = 1;
    INT I = 0,J = 0;
    INT CH = 0;
    如果(!csvFile)
    {
        的printf(广东话读文件\\ n请打开一个文件\\ n);
        返回-1;
    }
    做
    {
        CH =龟etc(csvFile);
        如果(CH ==',')
        {
            C ++;
        }
    }而(CH ='\\ n'!);
    fseek的(csvFile,0L,SEEK_SET);
    做
    {
        CH =龟etc(csvFile);
        如果(CH =='\\ n')
        {
            升++;
        }
    }而(CH = EOF!);
    焦炭** bigArr =(字符**)释放calloc(L * C,sizeof的(字符*));
    对于(i = 0; I< L * C;我++)
    {
        bigArr [I] =(字符*)释放calloc(10,sizeof的(炭));
    }
    fseek的(csvFile,0L,SEEK_SET);
    做
    {        CH =龟etc(csvFile);
        如果(CH ==',')
        {
            J ++;
        }
        否则,如果(CH =='\\ n')
        {
            我++;
        }
        其他
        {
            bigArr [I] [J] =(char)的CH;
        }
    }而(CH = EOF!);
}


解决方案

这是崩溃应该更像循环:

 枚举{MAX_FIELD_WIDTH = 10}; //包括空终结I = J = 0;
而((CH = GETC(csvFile))!= EOF)
{
    如果(CH ==''|| CH =='\\ n')
    {
        bigArr [我++] [J] ='\\ 0';
        J = 0;
    }
    其他
    {
        如果(J< MAX_FIELD_WIDTH - 1)
            bigArr [I] [J ++] = CH;
        //忽略其他字符过剩
}

警告:未经考验code

您code只是建立 L * C 字段值,这是很好的一个线性表。你可以选择线路领域 N 通过访问域 bigArr [N * C] bigArr [N * C + C - 1]。(从行0开始计数)

对于像重要的变量和 C ,我用更长的名称,如(或)和 COLS 。仍然不长,但更有意义。单字符名称应以有限的范围内使用。

请注意,这code忽略CSV格式的细微之处,如用双引号内的逗号领域,让双引号领域里单独换行。它也忽略在改变行场的数量的可能性。如果code保持跟踪行号,将有可能同时处理太多字段(忽略额外)太少字段(丢失字段创建空的条目)。如果code是$ P $对扫描文件是聪明,它可以保持每行列的最小和最大数目的记录以及行数。问题然后可以过诊断。

使用一个更复杂的存储器管理方案,它也将是可能的扫描该文件仅一次,它具有的优点,如果该文件实际上是一个终端或管道,而不是一个磁盘文件。它也可以处理,而不是限制他们到10字节,包括终端的空字节任意长的字段值。


在code应该检查该文件可以打开,并关闭它,当它完成。目前的功能接口是:

  INT changeValue(INT线,诠释关口,焦炭海峡[],为const char *路径)

但前三个值被示出的code忽略。这可能是因为最终的code会改变读出的值中的一个,然后重写文件。 presumably,如果要求改变一个不存在的列或行会报错。这些相对较小的infelicities可能是由于最小化,使code类于MCVE(如何创建一个最小的,完整的,可验证和实例?)。

I tried make a code to read a csv file and change one value by getting line and column. In the first I read the file to check how many lines and cols up there, and than I create a dynamic 2D array- every line is the line on the file. actually make the file in 2D array. and than I will change the value of the chosen line and col and write the whole array back to the file. someone know why it's crashed? it's crashed in the first line of -

bigArr[i][j]=(char)ch;

the function:

int changeValue(int line, int col, char str[],const char* path)
{
    FILE* csvFile = fopen(path, "r");
    char arr[VERY_BIG_MEMORY];
    int l = 0, c = 1;
    int i = 0,j=0;
    int ch = 0;
    if (!csvFile)
    {
        printf("Cant read the file\nPlease open a file\n");
        return -1;
    }
    do
    {
        ch = fgetc(csvFile);
        if (ch == ',')
        {
            c++;
        }
    } while (ch !='\n');
    fseek(csvFile, 0L, SEEK_SET);
    do
    {
        ch = fgetc(csvFile);
        if (ch == '\n')
        {
            l++;
        }
    } while (ch!=EOF);
    char** bigArr = (char**)calloc(l*c,sizeof(char*));
    for (i = 0; i < l*c; i++)
    {
        bigArr[i] = (char*)calloc(10,sizeof(char));
    }
    fseek(csvFile, 0L, SEEK_SET);
    do
    {

        ch = fgetc(csvFile);
        if (ch == ',')
        {
            j++;
        }
        else if (ch == '\n')
        {
            i++;
        }
        else
        {
            bigArr[i][j]=(char)ch;
        }
    } while (ch != EOF);
}

解决方案

The loop that's crashing should be more like:

enum { MAX_FIELD_WIDTH = 10 };  // Including null terminator

i = j = 0;
while ((ch = getc(csvFile)) != EOF)
{
    if (ch == ',' || ch == '\n')
    {
        bigArr[i++][j] = '\0';
        j = 0;
    }
    else
    {
        if (j < MAX_FIELD_WIDTH - 1)
            bigArr[i][j++] = ch;
        // else ignore excess characters
}

Warning: untested code!

Your code is simply creating a linear list of l * c field values, which is fine. You can pick the fields for line n by accessing fields bigArr[n * c] through bigArr[n * c + c - 1] (counting from line 0).

For important variables like l and c, I use longer names such as rows (or lines) and cols. Still not long, but more meaningful. Single character names should be used with limited scope.

Note that this code ignores subtleties of the CSV format such as fields with commas inside double quotes, let alone newlines within double quoted fields. It also ignores the possibility of varying numbers of fields in the lines. If the code kept track of line numbers, it would be possible to handle both too many fields (ignoring the extra) and too few fields (creating empty entries for missing fields). If the code that pre-scans the file was cleverer, it could keep a record of the minimum and maximum number of columns per line as well as the number of lines. Problems could then be diagnosed too.

With a more complex memory management scheme, it would also be possible to scan the file just once, which has advantages if the file is actually a terminal or pipe, rather than a disk file. It could also handle arbitrarily long field values instead of restricting them to 10 bytes including the terminal null byte.


The code should check that the file could be opened, and close it when it is finished. The current function interface is:

int changeValue(int line, int col, char str[], const char* path)

but the first three values are ignored by the code shown. This is probably because the final code will change one of the values read and then rewrite the file. Presumably, it would report an error if asked to change a non-existent column or line. These relatively minor infelicities are probably due to the minimization to make the code resemble an MCVE (How to create a Minimal, Complete, and Verifiable Example?).

这篇关于阅读.csv文件的一些code坠毁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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