我正在准备一个读取文件的程序:
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 256
int main(int argc, char** argv) {
FILE *fp;
char currLine[MAXLEN];
char **fileLines = malloc(MAXLEN * sizeof(char *));
for (int i = 0; i < MAXLEN; i++) {
fileLines[i] = malloc(MAXLEN * sizeof(char));
}
int lineCounter = 0;
fp = fopen("sample.txt", "r");
while (fgets(currLine, sizeof(currLine), fp)) {
fileLines[lineCounter] = currLine;
printf("%s", fileLines[lineCounter]);
lineCounter++;
}
printf("\n\n");
for (int i = 0; i < lineCounter; i++) {
printf("%s\n", fileLines[i]);
}
/*for (int i = 0; i < MAXLEN; i++) {
free(fileLines[i]);
}*/
free(fileLines);
fclose(fp);
return 0;
}
在 while 循环中,我从文本文件 sample.txt
中读取了一行文件:
first line
2nd
linea tres
#4
并尝试将字符数组分配给双指针中的字符指针之一,然后打印。在那一刻,打印正确,但一旦在循环之外,我再次打印每个项目,它们都打印最后一个元素:
输出:
first line
2nd
linea tres
#4
#4
#4
#4
#4
据此,我怀疑“赋值”实际上是指向局部变量 currline
,它的最后一个值为 #4
。那么我怎样才能正确分配读取的行而不是指向字符数组呢?感谢您提供的建议帮助
最佳答案
在读取文件的循环中,必须去掉结尾的换行符并将读取的每一行的内容复制到数组中。您当前为读取的每一行存储一个指向行缓冲区的指针。字符串数组中的所有行都指向同一个缓冲区,该缓冲区最多保存从文件中读取的最后一行。
这是这个循环的改进版本:
while (lineCounter < MAXLEN && fgets(currLine, sizeof(currLine), fp)) {
currLine[strcspn(currLine, "\n")] = '\0';
strcpy(fileLines[lineCounter], currLine);
printf("%s\n", fileLines[lineCounter]); // debug
lineCounter++;
}
这个错误也解释了为什么你不能释放 fileLines
数组中的行。这些指针不再指向分配的空间,在传递给 free()
时调用未定义的行为。
请注意,您可以通过这种方式为从文件中读取的每一行分配确切的空间,而不是预先分配完整的行数组:
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 256
int main(int argc, char** argv) {
char currLine[MAXLEN];
char **fileLines = malloc(MAXLEN * sizeof(char *));
for (int i = 0; i < MAXLEN; i++) {
fileLines[i] = NULL;
}
int lineCounter = 0;
FILE *fp = fopen("sample.txt", "r");
if (fp == NULL)
return 1;
while (lineCounter < MAXLEN && fgets(currLine, sizeof(currLine), fp)) {
currLine[strcspn(currLine, "\n")] = '\0';
fileLines[lineCounter] = strdup(currLine);
lineCounter++;
}
fclose(fp);
for (int i = 0; i < lineCounter; i++) {
printf("%s\n", fileLines[i]);
}
for (int i = 0; i < lineCounter; i++) {
free(fileLines[i]);
}
free(fileLines);
return 0;
}
关于指向字符数组的字符指针而不是赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38647772/