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

使用printf输出ReadFile读取的缓冲区出现乱码问题求助

问题解决:ReadFile读取后printf输出乱码

核心原因

printf的%s格式符要求输出的字符串必须以**空字符'\0'**结尾,但ReadFile仅负责将文件内容写入缓冲区,不会自动添加这个终止符。当缓冲区未被'\0'填充时,printf会持续读取缓冲区之外的内存数据,直到随机遇到'\0',这就是末尾乱码的根源。

此外你的代码还有两处潜在问题:

  • GetLastError()调用时机错误:只有当ReadFile返回FALSE时,该函数的返回值才有意义,当前无论读取成功与否都调用,会拿到无关的错误码。
  • 未检查CreateFile返回值:如果文件打开失败,hFile会是INVALID_HANDLE_VALUE,后续操作会引发异常。

修复后的代码

#include <windows.h>
#include <stdio.h>

#define BUFFER_SIZE 24

int main()
{
    HANDLE hFile = CreateFile(L"test.txt",               
        GENERIC_READ,          
        FILE_SHARE_READ,       
        NULL,                  
        OPEN_EXISTING,         
        FILE_ATTRIBUTE_NORMAL, 
        NULL);                 

    // 先校验文件句柄有效性
    if (hFile == INVALID_HANDLE_VALUE)
    {
        printf("文件打开失败,错误码:%d\n", GetLastError());
        return 1;
    }

    CHAR inBuffer[BUFFER_SIZE] = {0}; // 初始化缓冲区为0,确保末尾自带'\0'
    DWORD nNumberOfBytesRead;

    // 预留1字节给终止符,避免缓冲区溢出
    BOOL reading_result = ReadFile(hFile,
        inBuffer,
        BUFFER_SIZE - 1,
        &nNumberOfBytesRead,
        NULL);

    if (!reading_result)
    {
        printf("读取文件失败,错误码:%d\n", GetLastError());
        CloseHandle(hFile);
        return 1;
    }

    // 手动添加终止符(可选,但读满缓冲区时必须)
    inBuffer[nNumberOfBytesRead] = '\0';

    printf("读取成功,文本内容:%s\n", inBuffer);

    CloseHandle(hFile);
    return 0;
}

关键修复点

  • 初始化缓冲区为0:通过CHAR inBuffer[BUFFER_SIZE] = {0};让缓冲区所有字节默认是'\0',确保即使读满缓冲区,末尾也有终止符。
  • 预留终止符空间:读取时仅请求BUFFER_SIZE - 1字节,避免填满缓冲区后无法添加'\0'。
  • 正确校验API返回值:先检查CreateFile的句柄,再判断ReadFile的返回结果,仅在API失败时调用GetLastError()。
  • 手动添加终止符:即使缓冲区已初始化0,手动添加能更稳妥地保证读取内容后紧跟'\0'。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 18:12:41