如何将ReadFile与wchar_t一起使用?

问题描述 投票:0回答:2

考虑以下两个函数,第一个函数使用 Windows API 函数

ReadFile()
CreateFileW()
,而第二个函数使用
fopen()
fgetws()
,从名为
data.txt
的文件中读取非英语文本.

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

请注意,

fopen()
具有定义要使用的字符编码的
ccs=UTF-8
,而
read_file_2()
没有类似的东西。

DWORD read_file_2()
{
    wchar_t wstr[512];
    BOOL success = FALSE;
    DWORD dwRead, total =0;
    HANDLE handle = CreateFileW(L"data.txt",
                                GENERIC_READ,
                                0,
                                NULL,
                                3,
                                FILE_ATTRIBUTE_NORMAL,
                                NULL);
    if (handle == INVALID_HANDLE_VALUE)
        return -1;
    do
    {   
        success = ReadFile(handle, wstr, 20, &dwRead, NULL);
        total += dwRead;
    } while(!success || dwRead == 0);

    wstr[total] = L'\0';
    wprintf(L"%ls\n",wstr);
    return 0;
}

void read_file_1()
{
    wchar_t converted[20];
    FILE * ptr;view=msvc-170
    ptr = fopen("data.txt", "rt+,ccs=UTF-8");
    fgetws(converted, 20, ptr);
    wprintf(L"%ls\n", converted);
    fclose(ptr);
}

int main()
{
    _setmode(fileno(stdin), _O_U8TEXT);
    _setmode(fileno(stdout), _O_U8TEXT);
    read_file_1();
    read_file_2();
}

如何使用

ReadFile()
从文本文件中读取
wchar_t
字符串并将其输出到终端而不将其变成垃圾文本?

 Шифрование.txt  ال
퀠킨톸톄킀킾킲킰킽킸♥

data.txt
实际内容:

 Шифрование.txt  العربية.txt
c winapi utf-8 readfile
2个回答
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
);

注意,如果编译器有

wchar_t

  • WCHAR
    wchar_t
  • LPWSTR
    wchar_t *
  • LPCWSTR
    const wchar_t *

0
投票

问题在于

ReadFile()
不读取字符串,甚至字符。它读取字节

由于它不读取字符串,因此它也不会像字符串那样“空终止”数据。 您需要确保它读取足够的字节,并且如果它是字符串,则以空终止缓冲区。

通过使用循环,您有一个良好的开始,但是您的循环会覆盖循环最后一次迭代中读取的内容,从而使您丢失数据。

您需要在循环中传递一个指向缓冲区末尾的指针。

正如我在评论中已经提到的,请确保循环正常工作(例如,如果出现错误,则不会进入无限循环)。

© www.soinside.com 2019 - 2024. All rights reserved.