我编写了一个函数,它接受一个文件并将每一行存储在一个字符串数组中。
这里是涉及到的函数:
char **get_lines(FILE *file) {
int MAX_LINE_LENGTH = 2048;
int num_lines = 19;
char **lines = malloc(sizeof(char *) * num_lines);
// Make sure to start at the beginning of the file
fseek(file, 0L, SEEK_SET);
char *line = malloc(MAX_LINE_LENGTH);
int i = 0; // index counter for lines
while (fgets(line, MAX_LINE_LENGTH, file)) {
// Only add to lines if the line is not a single newline character
if (strcmp(line, "\n")) {
int len = strlen(line);
// Remove the last character as
// it should always be a newline character
if (len < MAX_LINE_LENGTH) {
line[len-1] = '\0';
}
lines[i] = malloc(strlen(line));
lines[i++] = line;
printf("%s\n", lines[i-1]); // This prints the lines correctly.
}
}
for (int x=0; x < num_lines; x++) {
// This prints strings containing only a newline character.
printf("%s", lines[x]);
}
return lines;
}
令我困惑的是,如果我在将它添加到数组后立即打印该行(在 while 循环内),则会打印正确的字符串。但是,如果我在 lines
定义完成后打印每一行(在 while 循环之外),它只会打印包含换行符的字符串。
这可能是什么原因造成的?
编辑 在不修改程序之后,现在第二个 printf 语句不会向控制台打印任何内容。
如果有帮助,我正在使用 CLion。
最佳答案
代码正在泄漏内存,因为它忽略了 malloc 内部循环,并且正在将 line 的相同地址分配给 lines[i]
char **get_lines(FILE *file) {
int MAX_LINE_LENGTH = 2048;
int num_lines = 19;
char **lines = malloc(sizeof(char *) * num_lines);
// Make sure to start at the beginning of the file
fseek(file, 0L, SEEK_SET);
char *line = malloc(MAX_LINE_LENGTH);
int i = 0; // index counter for lines
while (fgets(line, MAX_LINE_LENGTH, file)) {
// Only add to lines if the line is not a single newline character
if (strcmp(line, "\n")) {
int len = strlen(line);
// Remove the last character as
// it should always be a newline character
if (len < MAX_LINE_LENGTH) {
line[len-1] = '\0';
}
lines[i] = malloc(strlen(line));
strncpy(lines[i], line, len);
i++;
printf("%s\n", lines[i-1]); // This prints the lines correctly.
}
}
for (int x=0; x < num_lines; x++) {
// This prints strings containing only a newline character.
printf("%s", lines[x]);
}
return lines;
}
关于c - 逐行存储文件的功能会产生奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50418040/