这是什么 ?在读取用Unicode编码的文本文件后,在控制台输出的开头?

Roo*_*oot 2 c c++ unicode winapi

我一直在修补读取文件(用Unicode编码的文本文件),出于某种原因,我在输出的开头有一个问号.

这是代码.

#include <iostream>

#include <Windows.h>
#include <fcntl.h>
#include <io.h>

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

    _setmode(_fileno(stdout), _O_U16TEXT); //Making sure the console will 
                                           //display the  wide characters 
                                           //correctly. See below for link

    LARGE_INTEGER li;
    GetFileSizeEx(hFile,&li); 

    WCHAR* pBuf = new WCHAR[li.QuadPart / sizeof(WCHAR)]; //Allocating space for 
                                                          //the file.

    DWORD dwRead = 0;
    BOOL bFinishRead = FALSE;
    do
    {
        bFinishRead = ReadFile(hFile,pBuf,li.QuadPart,&dwRead,NULL);
    } while(!bFinishRead);

    pBuf[li.QuadPart / sizeof(WCHAR)] = 0; //Making sure the end of the output 
                                           //is null-terminated.

    std::wcout << pBuf << std::endl;

    std::cin.get();

    return 1;
}
Run Code Online (Sandbox Code Playgroud)

dog.txt

One Two Three
Run Code Online (Sandbox Code Playgroud)

控制台输出

?One Two Three
Run Code Online (Sandbox Code Playgroud)

我已经通过确保输出的结尾是空终止而消除了很多乱码但是?一开始让我困惑.

至于

_setmode(_fileno(stdout), _O_U16TEXT);
Run Code Online (Sandbox Code Playgroud)

请参阅Windows控制台应用程序中的输出unicode字符串

注意:我的代码是面向Windows的,如果可能的话,我打算保持这种方式.

谢谢.

eca*_*mur 6

它可能是一个字节顺序标记(BOM).标准做法是在UTF-16文本文件的开头插入BOM,以确保它可以在不同的端系统上正确读取(其中编码UTF-16双字节值的各个字节的顺序不同) .您可以通过检查第一个是否wchar_t是代码点(U+FEFF即具有值)来剥离它0xfeff.