2

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

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

发生的第一件事是调用 C# 代码打开 Microsoft Word 并将文档中的文本转换为字节数组。

byte document __gc[];
document = word->ConvertToArray(filename);

文件内容如下:

{84, 101, 115, 116, 32, 68, 111, 99, 117, 109, 101, 110, 116, 13, 10}

最终成为以下字符串:“测试文档”。

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

byte __pin * value;

value = &document[0];

LPTSTR image;
image = (LPTSTR)malloc( document->Length + 1 );

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

췍췍췍췍췍췍췍췍﷽﷽����˿於潁

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

memcpy(image,value,document->Length);

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

敔瑳䐠捯浵湥൴촊﷽﷽����˿於潁

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

4

1 回答 1

10

首先,您应该了解一些有关文本数据及其表示方式的知识。可以帮助您入门的参考是每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最低要求(没有借口!)

byte只是 typedef 或用于charor的东西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);

我们调用该函数MultiByteToWideChar()两次,一次是为了确定需要多大的缓冲区来保存转换的结果,第二次是传入我们分配的缓冲区来进行实际的转换。

CP_ACP指定源编码,您需要查看 API 文档以确定该值的真正含义。CP_ACP代表“代码页:Ansi 代码页”,这是微软对“非 Unicode”程序的编码集的说法。API 可能正在使用其他东西,比如CP_UTF8(我们希望)或 1252 或其他东西。

您可以在此处查看有关 MultiByteToWideChar 的其余文档以找出其他参数。


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

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


上面的代码实际上并不是很好的 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);

(假设使用的编码是 UTF-8。对于任何其他编码,char您必须使用不同的方面。)codecvt

于 2012-12-14T23:01:21.880 回答