【问题标题】:Trying to read file into dynamically allocated 2d array试图将文件读入动态分配的二维数组
【发布时间】:2015-06-14 05:22:40
【问题描述】:

我正在尝试将文件读入动态分配的二维数组,但我不断打印出同一行。我放入这段代码的文件是一个 .txt,有 1000 行。最后的打印是检查数组是否获取正确的数据。最后,我试图重新分配代码以适应放入数组的行数。谢谢 :)

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



int main(void)
{
    char buffer[349];
    char *del = "";
    int i = 0;
    int count = 0;
    int len = 100;
    int row = 10;
    int max = 10;
    char** d;

    d = malloc(row * sizeof(char*));

    for(i = 0; i < row; i++)
    {
        d[i] = malloc(349);
    }
    i = 0;



    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
    {
        d[i] = buffer;
        i++;
        if(i == max)
        {
            d = realloc(d, sizeof(d)*2);

            for(i = max; i <= max*2; i++)
            {
                d[i] = malloc(349);
            }
            max = max * 2;
            printf("reallocating to %d\n", max);
        }

    }

    for(i = 0; i < 20; i++)
    {   
        printf("%s\n", d[i]);
        printf("%lu\n", sizeof(d[i])); 
    }
}

txt 文件上的示例行:

2152,1,MAIN,SOCW,6390,006,22913,IND - 独立研究,0,1,1,0,0,12:00 AM,12:00 AM,N,N,N,N, N,N,N,01-20-2015,05-08-2015

文件中大约有 1000 行这样的行。

【问题讨论】:

  • 1)d[i] = buffer;改为strcpy(d[i], buffer);
  • 2)d = realloc(d, sizeof(d)*2); --> d = realloc(d, sizeof(*d)*max*2);
  • 3)for(i = max; i &lt;= max*2; i++) --> for(i = max; i &lt; max*2; i++)
  • 4) printf("%lu\n", sizeof(d[i])); --> printf("%lu\n", strlen(d[i]));
  • 5)这部分i到其他变量for(int j = max; j &lt; max*2; j++){ d[j] = malloc(349);}

标签: c arrays dynamic 2d allocation


【解决方案1】:

d 看起来不像任何东西的“二维数组”。数组是连续的。你的分配不是。我建议您更改d 的类型并避免过度分配。

char (*d)[349] = NULL;
size_t d_size = 0;

检查d_size是否为二进制幂(2的幂)来判断何时调整大小,并通过加倍调整大小:

if ((d_size & (d_size + 1)) == 0) {
    void *temp = realloc(d, (2 * d_size + 1) * sizeof *d);
    if (temp == NULL) {
        perror(realloc);
        exit(EXIT_FAILURE);
    }
    d = temp;
}

因为d 开始于NULLd_size 一个二进制幂(0),所以需要在分配之前进行容量检查。结果,您可以消除buffer

没有必要存储d 的容量,因为我们知道这将是我们通过重复递增d_size 得到的第一个二进制幂。 d_size 变成你的 i,如果你愿意的话。


除此之外,BLUEPIXY 还为您在 cmets 中的问题提供了解决方案。经过一次更正,这些是:

  1. strcpy(d[i], buffer);
  2. d = realloc(d, sizeof(*d)*max*2);
  3. for(int j = max; j &lt; max*2; j++){ d[j] = malloc(349);}
  4. printf("%zu\n", strlen(d[i]));

至少需要这四个才能使您的程序正常运行(无论这意味着什么),但您还应该考虑以下两个:

  • d = realloc(d, ...); 失败并返回NULL 时,您之前的@​​987654342@ 值会发生什么变化?它泄漏到稀薄的空气中。您应该将d 的返回值存储到temp 变量中(如下所示)并在继续之前检查NULL
  • 不要忘记freemalloc/realloc'd 的任何记忆。

将其中少数仍然适用的内容整合到我目前所学的内容中:

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

int main(void)
{
    char (*d)[349] = NULL;
    size_t d_size = 0;

    for (;;)
    {
        if ((d_size & (d_size + 1)) == 0)
        {
            void *temp = realloc(d, (2 * d_size + 1) * sizeof *d);
            if (temp == NULL)
            {
                break;
            }
            d = temp;
        }

        if (fgets(d[d_size], sizeof d[d_size], stdin) == NULL) {
            break;
        }

        d_size++;
    }

    for (size_t i = 0; i < d_size; i++)
    {   
        printf("%s\n", d[i]);
        printf("%zu\n", strlen(d[i])); 
    }

    free(d);
}

【讨论】:

    猜你喜欢
    • 2021-10-26
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    相关资源
    最近更新 更多