英文:
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->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;
}
I read the file via the following:
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
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->elements[array->size++] = strdup(element);
or:
const size_t n = strlen(element);
array->elements[array->size] = malloc(n + 1);
memcpy(array->elements[array->size], element, n + 1);
array->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(&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 array. And within the function all dynamically allocated pointers are set with this address
array->elements[array->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->capacity = capacity;
array->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->elements
in the left and the right sides of the assignment in this statement
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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论