为什么我用WriteFile写入文件的每个字符之间都有空格?

PiK*_*Chu 0 c++ windows unicode winapi

这是我的代码:

WCHAR msg[] = L"ReplaceFile:";
::WriteFile( hFile, msg, lstrlenW(msg) * sizeof(WCHAR), &nBytes, NULL );  
Run Code Online (Sandbox Code Playgroud)

我使用OPEN_ALWAYS模式创建了该文件,然后将一些const字符串写入该文件。该文件将显示“ ReplaceFile”,如下所示:替换文件。

有人可以告诉我如何使其正常吗?为什么?提前致谢。

Rem*_*eau 5

WCHAR是的别名wchar_t,在Windows上为2个字节。Windows上的宽字符串以UTF-16LE编码。在UTF-16中,每个元素(称为代码单元)的大小为2字节(16位),其中Unicode代码点U-0000-U-FFFF占用一个代码单元,而更高的代码点则占用两个代码单元。

您的宽字符串仅包含小于0x0080的ASCII字符,因此它们每个使用不超过7位,至少将9位设置为0。因此,写入文件的每个其他字节的值均为0x00,即不是可显示的字符,因此您看到的是多余的空格。

您的宽字符串L"ReplaceFile:"由UTF-16LE中的以下字节组成:

0x52 0x00 // R
0x65 0x00 // e
0x70 0x00 // p
0x6C 0x00 // l
0x61 0x00 // a
0x63 0x00 // c
0x65 0x00 // e
0x46 0x00 // F
0x69 0x00 // i
0x6C 0x00 // l
0x65 0x00 // e
0x3A 0x00 // :
Run Code Online (Sandbox Code Playgroud)

您应该阅读以下文章:

每个软件开发人员绝对,肯定必须绝对了解Unicode和字符集(无借口!)

话虽如此,UTF-16并不是将字符串存储在文件中的最佳选择。在大多数语言中,UTF-8比UTF-16压缩得多,并且向后兼容ASCII。在Windows上,可以在WideCharToMultiByte()将宽字符串写入文件之前使用该函数(或类似的函数/库)转换宽字符串:

WCHAR msg[] = L"ReplaceFile:";
int len = WideCharToMultiByte(CP_UTF8, 0, msg, lstrlenW(msg), NULL, 0, NULL, NULL);
CHAR *converted = new CHAR[len];
WideCharToMultiByte(CP_UTF8, 0, msg, lstrlenW(msg), converted, len, NULL, NULL);
::WriteFile( hFile, converted, len * sizeof(CHAR), &nBytes, NULL );  
delete [] converted;
Run Code Online (Sandbox Code Playgroud)

  • 没有任何异常。这是完全正常和标准的编码。他应该问的是“如何以一种没有额外的空值/空格的方式对其进行编码”。答案是使用`WideCharToMultiByte()`或类似函数将宽字符串从UTF-16转换为更紧凑的编码,例如UTF-8。 (2认同)