【问题标题】:Reading a file in C on Linux在 Linux 上用 C 语言读取文件
【发布时间】:2021-10-18 23:55:58
【问题描述】:

如何在 C 中的 Linux 上将文件读入字符串? 我想出了一些代码,但它不起作用,我知道为什么。 fgetc() 总是返回 -1。

文件结构是这样的

.:
Files/
main.c
makefile

./Files:
test

main.c的内容:

#include <stdio.h>

int fileLength(const char filePath[]);
void readFile(const char filePath[], char* outString);

int main()
{
    char fileContents[fileLength("Files/test")];
    readFile("Files/test", &fileContents);
    printf("DEBUG: Address of fileContents is 0x%x\n", &fileContents);
    printf("File contents:\n%s\n", fileContents);
    
    return 0;
}

int fileLength(const char filePath[])
{
    //Open the file
    FILE* file;
    
    if ((file = fopen(filePath, "r")) == NULL)
    {
        printf("ERROR: File (%s) cannot be opened.\n", filePath);
        return -1;
    }
    
    //Find the length
    fseek(file, 0, SEEK_END);
    return ftell(file);
}

void readFile(const char filePath[], char* outString)
{
    FILE* file;
    
    //File reading
    printf("DEBUG: File path is %s\n", filePath);
    if ((file = fopen(filePath, "r")) == NULL)
    {
        printf("ERROR: File (%s) cannot be opened.\n", filePath);
        exit(1);
    }
    
    //Get length of file and allocate the according amount of memory
    fseek(file, 0, SEEK_END);
    int fileLength = ftell(file);
    printf("DEBUG: File length is %i\n", fileLength);
    
    //Allocate string
    char fileContent[fileLength];
    
    //Read file to string
    printf("DEBUG: File contents as digits:\n");
    for (int i = 0; i < fileLength; i++)
    {
        fileContent[i] = fgetc(file);
        printf("%d ", fileContent[i]);
    }
    printf("\n");
    printf("DEBUG: Contents of file are:\n%s\n", fileContent);
    fclose(file);
    
    printf("DEBUG: outString is pointing to 0x%x\n", outString);
    
    *outString = fileContent;
}

输出通常只是一堆问号菱形的东西(在终端中运行),它们与文件的长度相匹配,最后还有一些其他随机字符。每次运行程序时,末尾的字符都会改变。

【问题讨论】:

  • fseek(file, 0, SEEK_END); 使文件指针位于文件末尾。这就是fgetc 失败的原因。获取文件长度后再次调用rewindfopen文件。另外,请注意fileLength 函数会导致资源泄漏,因为它不会fclose 文件。
  • 另外,char fileContent[fileLength]; 最终不是一个有效的字符串,因为它不是 NUL 终止的。使其大一个字节,并确保最后一个字节设置为 0。
  • 您需要查看整个代码 - 您使用 fileLength 来获取大小,但 readFile 无论如何都会做同样的事情 - 并且实际上不会将读取的内容发送回 main()。此外,您永远不会关闭您打开的任何文件。
  • 我按照 kaylum 所说的做了,调试打印有效,但 main() 中的“文件内容:\n%s\n”没有,我的作业有问题吗?
  • *outString = fileContent; 不会像您认为的那样做。事实上,编译器应该警告你。您不应该创建本地 fileContent 数组。改为直接写入outString

标签: c linux


【解决方案1】:

kaylum 是对的,解决方案是:

  • rewind()readFile() 中找到文件长度后
  • 完成后记得fclose()
  • 直接写信给outString,而不是使用fileContent

main.c的最终代码是:

#include <stdio.h>

int fileLength(const char filePath[]);
void readFile(const char filePath[], char* outString);

int main()
{
    char fileContents[fileLength("Files/test")];
    readFile("Files/test", &fileContents);
    printf("File contents:\n%s\n", fileContents);
    
    return 0;
}

int fileLength(const char filePath[])
{
    //Open the file
    FILE* file;
    
    if ((file = fopen(filePath, "r")) == NULL)
    {
        printf("ERROR: File (%s) cannot be opened.\n", filePath);
        return -1;
    }
    
    //Find the length
    fseek(file, 0, SEEK_END);
    int length = ftell(file);
    fclose(file);
    return length;
}

void readFile(const char filePath[], char* outString)
{
    FILE* file;
    
    //File reading
    if ((file = fopen(filePath, "r")) == NULL)
    {
        printf("ERROR: File (%s) cannot be opened.\n", filePath);
        exit(1);
    }
    
    //Get length of file and allocate the according amount of memory
    fseek(file, 0, SEEK_END);
    int fileLength = ftell(file);
    rewind(file);
    
    //Read file to string
    for (int i = 0; i < fileLength; i++)
        outString[i] = fgetc(file);
    fclose(file);
}

【讨论】:

    猜你喜欢
    • 2013-08-09
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 2014-12-13
    • 2011-03-01
    • 2011-12-08
    • 2019-11-01
    • 2017-03-18
    相关资源
    最近更新 更多