2

我一直在修改读取文件(以 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;
}

狗.txt

One Two Three

控制台输出

?One Two Three

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

至于

_setmode(_fileno(stdout), _O_U16TEXT);

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

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

谢谢。

4

1 回答 1

6

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

于 2012-07-02T17:20:51.770 回答