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

使用Windows API读取打印UTF-16LE文件无输出问题排查

解决Windows API读取UTF-16LE文件后控制台无输出问题

问题根源

你的代码读取UTF-16LE文件的逻辑是正确的,但控制台默认输出编码不支持直接打印宽字符(wchar_t),导致wcout输出的中文无法显示。另外,循环打印101个wchar_t会包含未读取的空字符,也会干扰正常输出。

修复步骤

1. 切换控制台输出编码为UTF-16

Windows控制台默认使用GBK或系统默认代码页,需手动切换到UTF-16(代码页1200)来适配宽字符输出:

SetConsoleOutputCP(CP_UTF16);

2. 仅打印有效读取字符

ReadFile返回的win_Transmission是读取的字节数,UTF-16每个字符占2字节,因此实际有效字符数为win_Transmission / sizeof(wchar_t),循环时只打印这些有效字符即可,避免输出空字符。

3. 优化C++宽字符流输出(可选)

默认情况下C++流与C标准库同步,可能影响宽字符输出效率和正确性,可禁用同步:

ios_base::sync_with_stdio(false);
wcin.tie(nullptr);
wcout.tie(nullptr);

修改后的完整代码

#include <Windows.h>
#include <iostream>
#include <cstddef>
#include <cstdint>

using namespace std;

int main() {
    // 设置控制台输出为UTF-16编码
    SetConsoleOutputCP(CP_UTF16);
    // 禁用流同步,优化宽字符输出
    ios_base::sync_with_stdio(false);
    wcin.tie(nullptr);
    wcout.tie(nullptr);

    HANDLE win_file = CreateFile2(
        L"C:\\win32tese.txt",
        GENERIC_READ, // 仅保留读权限,无需写权限
        FILE_SHARE_READ, // 添加共享读权限,避免文件被独占
        OPEN_EXISTING,
        NULL
    );
    if (win_file == INVALID_HANDLE_VALUE) {
        wcout << L"Failed to open file, error code: " << GetLastError() << endl;
        return -1;
    }

    wchar_t win_buffer[101] = {};
    DWORD win_Transmission = 0;
    BOOL win_Read = ReadFile(
        win_file,
        win_buffer, // 直接传缓冲区地址,无需取址符
        sizeof(win_buffer) - sizeof(wchar_t), // 预留一个位置存终止符,防止溢出
        &win_Transmission,
        NULL
    );
    wcout << L"Bytes transferred: " << win_Transmission << endl;

    if (!win_Read) {
        wcout << L"Read operation failed, error code: " << GetLastError() << endl;
    } else {
        size_t char_count = win_Transmission / sizeof(wchar_t);
        // 处理UTF-16LE的BOM(如果文件包含)
        size_t start_idx = (char_count > 0 && win_buffer[0] == 0xFEFF) ? 1 : 0;
        for (size_t i = start_idx; i < char_count; ++i) {
            wcout << win_buffer[i];
        }
        wcout << endl;
    }

    CloseHandle(win_file);
    return 0;
}

额外说明

  • 打开文件时,去掉不必要的GENERIC_WRITE权限,添加FILE_SHARE_READ可避免因文件被独占导致的打开失败;
  • 如果你的UTF-16LE文件包含BOM(开头为0xFFFE),代码中已添加判断跳过BOM,避免输出无效字符;
  • ReadFile的缓冲区大小设置为sizeof(win_buffer) - sizeof(wchar_t),确保预留一个位置存放字符串终止符,防止缓冲区溢出。

内容的提问来源于stack exchange,提问作者玩家蒸汽

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:31:17