如何将我的malloc + strcpy转换为C中的strdup?

时间:2014-01-04 18:06:36

标签: c string strdup

我正在尝试将csv数据保存在数组中以用于其他功能。我知道strdup对此有好处,但我不确定如何使它适用于我的情况。任何帮助表示赞赏!

数据存储在struct:

typedef struct current{
    char **data;
}CurrentData;

函数调用:

int main(void){
    int totalProducts = 0;
    CurrentData *AllCurrentData = { '\0' };
    FILE *current = fopen("C:\\User\\myfile.csv", "r");

    if (current == NULL){
        puts("current file data not found");
    }
    else{
        totalProducts = getCurrentData(current, &AllCurrentData);
    }
 fclose(current);
 return 0;
 }

我如何分配内存;

 int getCurrentData(FILE *current, CurrentData **AllCurrentData){

*AllCurrentData = malloc(totalProducts * sizeof(CurrentData));

    /*allocate struct data memory*/
    while ((next = fgetc(current)) != EOF){                                                 
        if (next == '\n'){
            (*AllCurrentData)[newLineCount].data = malloc(colCount * sizeof(char*));
            newLineCount++;
        }
    }
    newLineCount = 0;
    rewind(current);

    while ((next = fgetc(current)) != EOF && newLineCount <= totalProducts){                    

        if (ch != '\0'){
            buffer[i] = ch;
            i++;
            characterCount++;
        }

        if (ch == ',' && next != ' ' || ch == '\n' && ch != EOF){
            if (i > 0){
                buffer[i - 1] = '\0';
            }
            length = strlen(buffer);
            /*(*AllCurrentData)[newLineCount].data[tabCount] = malloc(length +  1);     /* originally was using strcpy */
            strcpy((*AllCurrentData)[newLineCount].data[tabCount], buffer);
            */
            (*AllCurrentData)[newLineCount].data[tabCount] = strdup(buffer);  /* something like this? */

            i = 0;
            tabCount++;

            for (j = 0; j < BUFFER_SIZE; j++){
                buffer[j] = '\0';
            }
        }

3 个答案:

答案 0 :(得分:0)

好的,我不会对你代码的其他部分发表评论,但是你可以使用strdup去除这一行(*AllCurrentData)[newLineCount].data = malloc(colCount * sizeof(char*));,这一行(*AllCurrentData)[newLineCount].data[tabCount] = strdup(buffer); /* something like this? */ 并用以下内容替换它们:(*AllCurrentData)[newLineCount].data = strdup(buffer);

答案 1 :(得分:0)

您定义了一个ptr AllCurrentData,但您应该将其设置为NULL。

CurrentData* AllCurrentData = NULL;

getCurrentData totalProducts中使用**data,这似乎有点儿 奇怪,因为它是main()中的局部变量,要么你有另一个 具有相同名称的全局变量或存在错误。

结构中的char line[255]; if ( fgets(line,sizeof(line),current) != NULL ) { char* token = strdup(strtok( line, "," )); ... } 似乎很奇怪,而不是你想要的 解析csv行并为它们创建适当的成员。你已经 有一个CurrentData数组,所以有另一个数组似乎很奇怪 在结构内部 - 我只是猜测因为你没有解释 那部分。

由于csv文件是基于行的,因此使用fgets()读取一行 从文件中,然后使用例如解析字符串strtok或只是 在分隔符后检查缓冲区。 strdup可以发挥作用, 当你取出一个令牌时,在它上面做一个strdup并将它存储在你的 结构

{{1}}

而不是分配可能足够(或不使用)的大缓冲区 当你从文件中读取时,realloc增加你的缓冲区。

那说有更快的方法从csv文件中提取数据,例如 你可以用fread读取整个文件,然后查找分隔符 并将这些设置为\ 0并在缓冲区中创建一个char指针数组。

答案 2 :(得分:0)

对于读取字符串数组的函数,我将从以下方法开始。这还没有经过测试甚至编译,但它是一个起点。

此示例未解决许多问题。对于文件中的所有行,4K字符的临时缓冲区大小可能足够大,也可能不足够大。文件中的文本行可能比指针数组中的元素多,并且函数没有指示发生这种情况。

对此的改进将是更好的错误处理。此外,它可能会被修改,以便指针数组在函数中分配一些大量,然后如果文件中的行数多于数组元素,则使用realloc()函数将指针数组放大一些大小。也许对文件大小进行检查并使用平均文本行长度也适合为指针数组提供初始大小。

// Read lines of text from a text file returning the number of lines.
// The caller will provide an array of char pointers which will be used
// to return the list of lines of text from the file.
int GetTextLines (FILE *hFile, char **pStringArrays, int nArrayLength)
{
    int  iBuffSize = 4096;
    int  iLineCount = 0;
    char tempBuffer [4096];

    while (fgets (tempBuffer, iBuffSize, hFile) && iLineCount < nArrayLength) {
        pStringArrays[iLineCount] = malloc ((strlen(tempBuffer) + 1) * sizeof (char));
        if (! pStringArrays[iLineCount])
            break;
        strcpy (pStringArrays[iLineCount], tempBuffer);
        iLineCount++; 
    }
    return iLineCount;
}