loa*_*per 0 c winapi utf-8 readfile
考虑以下两个函数,第一个函数使用 Windows API 函数ReadFile()和CreateFileW(),而第二个函数使用fopen()和fgetws(),从名为 的文件中读取非英语文本data.txt。
第一个函数输出垃圾文本,而第二个函数输出文件中的文本,没有任何问题。
\n请注意,fopen()hasccs=UTF-8定义了要使用的字符编码,而read_file_2()does 没有类似的内容。
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}\nRun Code Online (Sandbox Code Playgroud)\n如何从文本文件中ReadFile()读取wchar_t字符串并将其输出到终端而不将其转换为垃圾文本?
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}\nRun Code Online (Sandbox Code Playgroud)\n实际内容data.txt:
\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\nRun Code Online (Sandbox Code Playgroud)\n
您可以使用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,
WCHAR是wchar_tLPWSTR是wchar_t *LPCWSTR是const wchar_t *