在C中逐行存储文本文件的正确方法是什么?

huangapple go评论59阅读模式
英文:

What's the proper way to store a text file line by line in an array in C?

问题

以下是您提供的代码的中文翻译部分:

我有一个包含可变长度行的文本文件,我想使用C语言将其存储在动态数组中。

以下是动态数组的实现:

struct array {
    char **elements;
    long size;
    long capacity;
};

void array_init(struct array *array, long capacity)
{
    array->capacity = capacity;
    array->elements = malloc(capacity * sizeof(char*));
}

void array_push_back(struct array *array, char *element)
{
    if (array->size == array->capacity) {
        array->capacity *= 2;
        array->elements = realloc(array->elements, array->capacity * sizeof(char*));
    }
    array->elements[array->size++] = element;
}

我通过以下方式读取文件:

struct array array;
FILE *file = fopen(filename, "r");
const unsigned MAX_LENGTH = 256;
char buffer[MAX_LENGTH];

array_init(&array, 1000);

while (fgets(buffer, MAX_LENGTH, file))
{
     array_push_back(&array, buffer);
}

for (int i = 0; i < array.size; i++)
{
     printf(array.elements[i]);
}

printf 只打印数组的最后一个元素,而且次数等于数组的大小。我猜这是因为我将 buffer 的地址分配给了 array.elements[i],并且只更改了 buffer 的内容。

请问有谁可以帮助正确地从文件中读取并存储数据?

英文:

I have a text file with variable length lines which I would like to store in a dynamic array using c.

The following is the dynamic array implementation:

struct array {
    char **elements;
    long size;
    long capacity;
};

void array_init(struct array *array, long capacity)
{
    array-&gt;capacity = capacity;
    array-&gt;elements = malloc(capacity * sizeof(char*));
}

void array_push_back(struct array *array, char *element)
{
    if (array-&gt;size == array-&gt;capacity) {
        array-&gt;capacity *= 2;
        array-&gt;elements = realloc(array-&gt;elements, array-&gt;capacity * sizeof(char*));
    }
    array-&gt;elements[array-&gt;size++] = element;
}

I read the file via the following:

struct array array;
FILE *file = fopen(filename, &quot;r&quot;);
const unsigned MAX_LENGTH = 256;
char buffer[MAX_LENGTH];

array_init(&amp;array, 1000);

while (fgets(buffer, MAX_LENGTH, file))
{
     array_push_back(&amp;array, buffer);
}

for (int i = 0; i &lt; array.size; i++)
{
     printf(array.elements[i]);
}

printf prints the last element only as many times as large the array is. I guess it is because I assign buffer's address to array.elements[i] and only change the content of buffer.

Can someone please help with correctly reading from a file and storing it?

答案1

得分: 4

array->elements[array->size++] = element;

你一再将来自main的buffer指针存储到每个元素中。你需要复制字符串的内容。

array->elements[array->size++] = strdup(element);

或者:

const size_t n = strlen(element);
array->elements[array->size] = malloc(n + 1);
memcpy(array->elements[array->size], element, n + 1);
array->size++;
英文:

> array->elements[array->size++] = element;

You are storing a pointer to buffer from main over and over again to each element. You have to copy the content of the string.

array-&gt;elements[array-&gt;size++] = strdup(element);

or:

const size_t n = strlen(element);
array-&gt;elements[array-&gt;size] = malloc(n + 1);
memcpy(array-&gt;elements[array-&gt;size], element, n + 1);
array-&gt;size++;

答案2

得分: 1

In the while loop in main:

char buffer[MAX_LENGTH];

array_init(&array, 1000);

while (fgets(buffer, MAX_LENGTH, file))
{
     array_push_back(&array, buffer);
}

在主函数的while循环中:

char buffer[MAX_LENGTH];

array_init(&array, 1000);

while (fgets(buffer, MAX_LENGTH, file))
{
     array_push_back(&array, buffer);
}

you are passing the same array buffer to the function array_push_back. So the function gets a pointer to the first element of the array. And within the function, all dynamically allocated pointers are set with this address.

你将相同的数组 buffer 传递给函数 array_push_back。因此,函数获得了指向数组第一个元素的指针。在函数内部,所有动态分配的指针都将设置为这个地址。

You need to allocate dynamically a character array for each pointer and copy the string stored in the array buffer into the dynamically allocated array.

你需要为每个指针动态分配一个字符数组,并将存储在数组 buffer 中的字符串复制到动态分配的数组中。

Pay attention to that this function:

注意,这个函数:

void array_init(struct array *array, long capacity)
{
    array->capacity = capacity;
    array->elements = malloc(capacity * sizeof(char*));
}

does not initialize data member size to zero of the passed structure. It stays uninitialized.

并没有将传递的结构体的数据成员 size 初始化为零。它保持未初始化状态。

And using the same pointer array->elements on the left and the right sides of the assignment in this statement:

在这个语句中,在赋值的左边和右边都使用相同的指针 array->elements

array->elements = realloc(array->elements, array->capacity * sizeof(char*));

is unsafe. The function can return a null pointer, and the early allocated memory will be lost. You need to write something like:

是不安全的。该函数可能返回一个空指针,而之前分配的内存将会丢失。你需要编写类似以下的代码:

char **tmp = realloc(array->elements, 2 * array->capacity * sizeof(char*));

if (tmp != NULL)
{
    array->elements = tmp;
    array->capacity *= 2;
}
英文:

In the while loop in main

char buffer[MAX_LENGTH];

array_init(&amp;array, 1000);

while (fgets(buffer, MAX_LENGTH, file))
{
     array_push_back(&amp;array, buffer);
}

you are passing the same array buffer to the function array_push_back. So the function gets a pointer to the first element of array. And within the function all dynamically allocated pointers are set with this address

array-&gt;elements[array-&gt;size++] = element;

You need to allocate dynamically a character array for each pointer and copy the string stored in the array buffer into the dynamically allocated array.

Pay attention to that this function

void array_init(struct array *array, long capacity)
{
    array-&gt;capacity = capacity;
    array-&gt;elements = malloc(capacity * sizeof(char*));
}

does not initialize data member size to zero of the passed structure. It stays uninitialized.

And using the same pointer array-&gt;elements in the left and the right sides of the assignment in this statement

array-&gt;elements = realloc(array-&gt;elements, array-&gt;capacity * sizeof(char*));

is unsafe. The function can return a null pointer and the early allocated memory will be lost. You need to write something like

char **tmp = realloc(array-&gt;elements, 2 * array-&gt;capacity * sizeof(char*));

if ( tmp != NULL )
{
    array-&gt;elements = tmp;
    array-&gt;capacity  *= 2;
}

huangapple
  • 本文由 发表于 2023年6月1日 00:10:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375462.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定