我似乎在将字节数组(包含来自 word 文档的文本)转换为 LPTSTR (wchar_t *) 对象时遇到问题。每次执行代码时,我都会返回一堆不需要的 Unicode 字符。
我认为这是因为我没有在某处进行正确的调用,或者没有正确使用变量,但不太确定如何处理这个问题。希望这里有人能引导我朝着正确的方向前进。
我们调用 C# 代码以打开 Word 并将文档中的文本转换为字节数组,这首先发生在我们调用 C# 代码Microsoft。
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(image,value,document->Length);
这只会导致出现更多不需要的 Unicode 字符:
敔瑳䐠捯浵湥൴촊﷽﷽����˿於潁
我认为我们遇到的问题要么与我们如何在字节数组中存储值有关,要么可能与将数据从字节数组复制到 LPTSTR 变量有关。任何帮助解释我做错了什么,或任何为我指出正确方向的东西,将不胜感激。
首先,您应该了解文本数据及其表示方式。一个可以让你开始的参考是每个软件开发人员绝对、肯定地必须了解 Unicode 和字符集(没有借口!
byte
只是一个 typedef 或用于char
或unsigned char
的东西。因此,字节数组对字符串使用了一些char
编码。您需要实际从该编码(无论它是什么)转换为 适用于 Windowswchar_t
的 UTF-16 。以下是推荐在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
代表"codepage:Ansi codepage",这是Microsoft说"非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);
(假设使用的char
编码是 UTF-8。对于任何其他编码,您必须使用不同的codecvt
方面。