如何将 ReadFile 与 wchar_t 一起使用?

loa*_*per 0 c winapi utf-8 readfile

考虑以下两个函数,第一个函数使用 Windows API 函数ReadFile()CreateFileW(),而第二个函数使用fopen()fgetws(),从名为 的文件中读取非英语文本data.txt

\n

第一个函数输出垃圾文本,而第二个函数输出文件中的文本,没有任何问题。

\n

请注意,fopen()hasccs=UTF-8定义了要使用的字符编码,而read_file_2()does 没有类似的内容。

\n
DWORD read_file_2()\n{\n    wchar_t wstr[512];\n    BOOL success = FALSE;\n    DWORD dwRead, total =0;\n    HANDLE handle = CreateFileW(L"data.txt",\n                                GENERIC_READ,\n                                0,\n                                NULL,\n                                3,\n                                FILE_ATTRIBUTE_NORMAL,\n                                NULL);\n    if (handle == INVALID_HANDLE_VALUE)\n        return -1;\n    do\n    {   \n        success = ReadFile(handle, wstr, 20, &dwRead, NULL);\n        total += dwRead;\n    } while(!success || dwRead == 0);\n\n    wstr[total] = L\'\\0\';\n    wprintf(L"%ls\\n",wstr);\n    return 0;\n}\n\nvoid read_file_1()\n{\n    wchar_t converted[20];\n    FILE * ptr;view=msvc-170\n    ptr = fopen("data.txt", "rt+,ccs=UTF-8");\n    fgetws(converted, 20, ptr);\n    wprintf(L"%ls\\n", converted);\n    fclose(ptr);\n}\n\nint main()\n{\n    _setmode(fileno(stdin), _O_U8TEXT);\n    _setmode(fileno(stdout), _O_U8TEXT);\n    read_file_1();\n    read_file_2();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如何从文本文件中ReadFile()读取wchar_t字符串并将其输出到终端而不将其转换为垃圾文本?

\n
DWORD read_file_2()\n{\n    wchar_t wstr[512];\n    BOOL success = FALSE;\n    DWORD dwRead, total =0;\n    HANDLE handle = CreateFileW(L"data.txt",\n                                GENERIC_READ,\n                                0,\n                                NULL,\n                                3,\n                                FILE_ATTRIBUTE_NORMAL,\n                                NULL);\n    if (handle == INVALID_HANDLE_VALUE)\n        return -1;\n    do\n    {   \n        success = ReadFile(handle, wstr, 20, &dwRead, NULL);\n        total += dwRead;\n    } while(!success || dwRead == 0);\n\n    wstr[total] = L\'\\0\';\n    wprintf(L"%ls\\n",wstr);\n    return 0;\n}\n\nvoid read_file_1()\n{\n    wchar_t converted[20];\n    FILE * ptr;view=msvc-170\n    ptr = fopen("data.txt", "rt+,ccs=UTF-8");\n    fgetws(converted, 20, ptr);\n    wprintf(L"%ls\\n", converted);\n    fclose(ptr);\n}\n\nint main()\n{\n    _setmode(fileno(stdin), _O_U8TEXT);\n    _setmode(fileno(stdout), _O_U8TEXT);\n    read_file_1();\n    read_file_2();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

实际内容data.txt

\n
 \xd0\xa8\xd0\xb8\xd1\x84\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xb5.txt  \xd8\xa7\xd9\x84\n\xed\x80\xa0\xed\x82\xa8\xed\x86\xb8\xed\x86\x84\xed\x82\x80\xed\x82\xbe\xed\x82\xb2\xed\x82\xb0\xed\x82\xbd\xed\x82\xb8\xe2\x99\xa5\n
Run Code Online (Sandbox Code Playgroud)\n

ike*_*ami 5

您可以使用MultiByteToWideChar

#define MALLOC( t, n ) ( ( t* )malloc( sizeof( t ) * n ) )

int total_wchars = MultiByteToWideChar(
   CP_UTF8,       // CodePage
   0,             // dwFlags
   bytes,         // lpMultiByteStr  The bytes read using `ReadFile`/`read`.
   total_bytes,   // cbMultiByte        No need for NUL.
   NULL,          // lpWideCharStr
   0              // cchWideChar     0 = Get size incl NUL.
);

if ( total_wchars == 0 ) {
   // Error. Use GetLastError() and such.
   ...
}

LPWSTR wchars = MALLOC( WCHAR, total_wchars );

MultiByteToWideChar(
   CP_UTF8,       // CodePage
   0,             // dwFlags
   bytes,         // lpMultiByteStr
   total_bytes,   // cbMultiByte
   wchars,        // lpWideCharStr
   total_wchars   // cchWideChar
);
Run Code Online (Sandbox Code Playgroud)

请注意,如果编译器有wchar_t

  • WCHARwchar_t
  • LPWSTRwchar_t *
  • LPCWSTRconst wchar_t *