C逐行读取文件

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (21)

我编写了这个函数来读取文件中的一行:

const char *readLine(FILE *file) {

    if (file == NULL) {
        printf("Error: file pointer is null.");
        exit(1);
    }

    int maximumLineLength = 128;
    char *lineBuffer = (char *)malloc(sizeof(char) * maximumLineLength);

    if (lineBuffer == NULL) {
        printf("Error allocating memory for line buffer.");
        exit(1);
    }

    char ch = getc(file);
    int count = 0;

    while ((ch != '\n') && (ch != EOF)) {
        if (count == maximumLineLength) {
            maximumLineLength += 128;
            lineBuffer = realloc(lineBuffer, maximumLineLength);
            if (lineBuffer == NULL) {
                printf("Error reallocating space for line buffer.");
                exit(1);
            }
        }
        lineBuffer[count] = ch;
        count++;

        ch = getc(file);
    }

    lineBuffer[count] = '\0';
    char line[count + 1];
    strncpy(line, lineBuffer, (count + 1));
    free(lineBuffer);
    const char *constLine = line;
    return constLine;
}

该函数正确读取文件,并使用printf,我发现constLine字符串也正确读取。

但是,如果我使用这样的函数:

while (!feof(myFile)) {
    const char *line = readLine(myFile);
    printf("%s\n", line);
}

printf输出乱码。为什么?

提问于
用户回答回答于

在你的readLine函数中,你返回一个指向line数组的指针(严格来说,指向它的第一个字符的指针,但是这里的差别是不相关的)。由于它是一个自动变量(即“在堆栈上”),当函数返回时,内存将被回收。你会看到乱码,因为它printf已经把自己的东西放在堆栈上了。

你需要从函数中返回一个动态分配的缓冲区。你已经有一个,它是lineBuffer; 所有你需要做的就是截断它到所需的长度。

    lineBuffer[count] = '\0';
    realloc(lineBuffer, count + 1);
    return lineBuffer;
}

ADDED(响应后续问题的评论):readLine返回一个指向组成该行的字符的指针。这个指针是你需要处理这行内容的东西。free当你完成使用这些字符所占用的内存时,这也是你必须传递给你的。以下是您可以如何使用该readLine功能的方法:

char *line = readLine(file);
printf("LOG: read a line: %s\n", line);
if (strchr(line, 'a')) { puts("The line contains an a"); }
/* etc. */
free(line);
/* After this point, the memory allocated for the line has been reclaimed.
   You can't use the value of `line` again (though you can assign a new value
   to the `line` variable if you want). */
用户回答回答于

#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> int main(void) { FILE * fp; char * line = NULL; size_t len = 0; ssize_t read; fp = fopen("/etc/motd", "r"); if (fp == NULL) exit(EXIT_FAILURE); while ((read = getline(&line, &len, fp)) != -1) { printf("Retrieved line of length %zu :\n", read); printf("%s", line); } fclose(fp); if (line) free(line); exit(EXIT_SUCCESS); }

扫码关注云+社区