将字节数组的内容转换为wchar_t*

Chr*_*non 1 c++ bytearray wchar-t lptstr

我似乎在将字节数组(包含word文档中的文本)转换为LPTSTR(wchar_t*)对象时遇到问题.每次代码执行时,我都会收到一堆不需要的Unicode字符.

我认为这是因为我没有在某个地方进行正确的调用,或者没有正确使用变量,但不太确定如何处理这个问题.希望这里有人可以指导我朝着正确的方向前进.

我们首先调用C#代码来打开Microsoft Word并将文档中的文本转换为字节数组.

byte document __gc[];
document = word->ConvertToArray(filename);
Run Code Online (Sandbox Code Playgroud)

文件内容如下:

{84, 101, 115, 116, 32, 68, 111, 99, 117, 109, 101, 110, 116, 13, 10}
Run Code Online (Sandbox Code Playgroud)

最终成为以下字符串:"测试文档".

我们的下一步是分配内存以将字节数组存储到LPTSTR变量中,

byte __pin * value;

value = &document[0];

LPTSTR image;
image = (LPTSTR)malloc( document->Length + 1 );
Run Code Online (Sandbox Code Playgroud)

一旦我们执行了开始分配内存的行,我们的图像变量就会被一堆不需要的Unicode字符填充:

?????????????????
Run Code Online (Sandbox Code Playgroud)

然后我们做一个memcpy来传输所有数据

memcpy(image,value,document->Length);
Run Code Online (Sandbox Code Playgroud)

这只会导致出现更多不需要的Unicode字符:

?????????????????
Run Code Online (Sandbox Code Playgroud)

我认为我们遇到的问题要么与我们如何在字节数组中存储值有关,要么与我们将数据从字节数组复制到LPTSTR变量有关.任何帮助解释我做错了什么,或任何指向我正确方向的任何帮助将不胜感激.

bam*_*s53 7

首先,您应该了解一些有关文本数据及其表示方式的信息.一个让你开始的参考是绝对最低每个软件开发人员绝对,必须知道关于Unicode和字符集(没有借口!)

byte只是一个typedef或什么的char或unsigned char.所以字节数组char对字符串使用了一些编码.你需要实际上从那个编码转换成Windows的UTF-16 wchar_t.以下是在Windows上进行此类转换时推​​荐的典型方法:

int output_size = MultiByteToWideChar(CP_ACP,0,value,-1,NULL,0);
assert(0<output_size);
wchar_t *converted_buf = new wchar_t[output_size];
int size = MultiByteToWideChar(CP_ACP,0,value,-1,converted_buf,output_size);
assert(output_size==size);
Run Code Online (Sandbox Code Playgroud)

我们调用该函数MultiByteToWideChar()两次,一次计算出需要多大的缓冲区来保存转换结果,第二次调用我们分配的缓冲区来进行实际的转换.

CP_ACP指定源编码,您需要检查API文档以确定该值应该是什么.CP_ACP代表"代码页:安西代码页",这是微软说"非Unicode"程序的编码集的方式.API可能正在使用其他东西,例如CP_UTF8(我们可以希望)或1252或其他东西.

您可以在此处查看MultiByteToWideChar上的其余文档,以找出其他参数.


一旦我们执行了开始分配内存的行,我们的图像变量就会被一堆不需要的Unicode字符填充:

当你调用malloc()给你的内存是未初始化的,只是包含垃圾.在初始化之前看到的值无关紧要,您根本不应该使用该数据.唯一重要的数据是填充缓冲区的内容.MultiByteToWideChar()上面的代码也将自动为null终止字符串,因此您不会在未使用的缓冲区空间中看到垃圾(我们使用的分配缓冲区的方法不会留下任何额外的空间).


上面的代码实际上并不是很好的C++风格.这只是Win32提供的C风格API的典型用法.我喜欢做转换的方式(如果我被迫)更像是:

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> convert; // converter object saved somewhere

std::wstring output = convert.from_bytes(value);
Run Code Online (Sandbox Code Playgroud)

(假设使用的char编码是UTF-8.您必须使用不同的codecvtfacet进行任何其他编码.)