You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux环境下C语言读取文件到字符串时fgetc返回-1及乱码问题

问题根因与修复方案

核心错误点

  • fgetc返回-1的直接原因:使用fseek(file, 0, SEEK_END)获取文件长度后,未调用rewind(file)或者fseek(file, 0, SEEK_SET)将文件指针重置到文件开头,后续读取操作直接从文件结束位置开始,拿到的全是EOF(即-1),存入数组后对应字节为0xFF,在终端输出就会显示为菱形问号。
  • 输出末尾随机乱码原因:C语言字符串要求以\0作为结束标记,你的数组长度仅等于文件实际字节数,没有预留1字节的空间存储结束符,调用printf("%s")时会越界读取数组后的随机内存值,所以每次运行显示的末尾乱码都不一样。
  • 内容拷贝逻辑完全错误:readFile函数内的fileContent是函数栈上的局部数组,函数执行结束后该内存会被自动回收,且*outString = fileContent属于类型不匹配的错误赋值:*outString是char类型,fileContent是指针类型,该操作既没有把文件内容拷贝到main函数传入的fileContents数组中,还会造成内存访问错误。
  • 其他常见错误:
    • fileLength函数打开文件后没有调用fclose,存在文件资源泄漏
    • 文本模式下调用fseek + ftell获取文件长度属于C标准未定义行为,建议使用二进制模式rb打开文件
    • 调用exit函数需要引入<stdlib.h>头文件,否则编译会有隐式声明警告
    • 打印指针地址应该使用%p格式符,%x仅适用于输出无符号整数
    • main函数调用readFile时传&fileContents属于多余操作,数组名本身就是首元素地址,直接传fileContents即可

修复后完整代码

#include <stdio.h>
#include <stdlib.h>

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

int main()
{
    int len = fileLength("Files/test");
    // 多预留1字节存字符串结束符
    char fileContents[len + 1];
    readFile("Files/test", fileContents, len);
    printf("DEBUG: Address of fileContents is %p\n", (void*)fileContents);
    printf("File contents:\n%s\n", fileContents);
    
    return 0;
}

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

void readFile(const char filePath[], char* outString, int bufLen)
{
    FILE* file;
    
    printf("DEBUG: File path is %s\n", filePath);
    if ((file = fopen(filePath, "rb")) == NULL)
    {
        printf("ERROR: File (%s) cannot be opened.\n", filePath);
        exit(1);
    }
    
    fseek(file, 0, SEEK_END);
    int fileLength = ftell(file);
    printf("DEBUG: File length is %i\n", fileLength);
    // 重置文件指针到开头
    rewind(file);
    
    printf("DEBUG: File contents as digits:\n");
    for (int i = 0; i < fileLength && i < bufLen; i++)
    {
        outString[i] = fgetc(file);
        printf("%d ", outString[i]);
    }
    // 补充字符串结束符
    outString[fileLength < bufLen ? fileLength : bufLen] = '\0';
    printf("\n");
    printf("DEBUG: Contents of file are:\n%s\n", outString);
    fclose(file);
    
    printf("DEBUG: outString is pointing to %p\n", (void*)outString);
}

内容的提问来源于stack exchange,提问作者Dreary35

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:09:00