c++ - 为什么 mbstowcs 返回 "invalid multibyte character"

标签 c++ c utf-8 utf-16

"קמ"ד חיר!" 是从 gdb 中的变量打印粘贴的输入字符串拷贝。调用 mbstowcs 返回 -1,另一个输入为 NULL。关于问题出在哪里/如何解决这个问题有什么想法吗?

"\327\247\327\236"\327\223\327\227\327\231\327\250!\000\000\000" 是非ascii的字符串八进制字符

程序语言环境是 C。

最佳答案

mbtowcs 函数不处理 UTF-8 编码,没有您可以设置的区域设置让它将 UTF-8 转换为 wchar_t。因此,我将使用 Windows 示例,但总体思路在大多数操作系统上都是相同的。

在多字节字符集世界中,给定的八进制值可能没有一种含义,任何给定字符也可能没有一个八进制值。特定八进制值的含义以及字符的表示方式(或者甚至如果它可以表示)由 locale 决定。 .

当 mbstowcs 返回错误时,它基本上是在告诉您没有与传入的多字节字符等效的宽字符。这可能意味着没有 UNICODE 字符(不太可能但并非不可能),或者它可能意味着语言环境没有为给定的八进制值(或多字节字符情况下的八进制值序列)定义字符。

如果您没有明确设置您的语言环境(通过调用 setlocale ),那么您会根据您的系统配置获得一个语言环境。要检索您当前的语言环境,您可以调用 _get_current_locale .一旦您知道了您的语言环境,您就可以找出一个特定的八进制值代表什么字符(如果有的话),然后您可以找出 UNICODE 等价物(如果有的话)。

识别问题字符的一种方法是改变传递给 mbstowcs 的长度,直到找到导致错误的单个字符。一种蛮力方法可能是从 length=1 开始并增加它直到 mbstowcs 返回 -1。

7 月 25 日更新

从评论讨论中我们发现输入字符串(很可能)编码为 UTF-8。虽然最初的答案是正确的(就目前而言),但还不够。在 Windows 上,您无法创建将处理以 UTF-8 编码的字符的语言环境。

当遇到 UTF-8 时,我们可以调用 MultiByteToWideChar 而不是调用 mbtowcs|使用代码页 CP_UTF8 但该代码仅适用于 Windows...

BYTE bytes [] = {0xD7,0x99,0xD7,0x95,0xD7,0x97,0xD7,0x90,0xD7,0x99,0x20,0xD7,0x95,0xD7,0x9B,0xD7,0x98,0xD7,0xA8, 0x00};

int result;

// get length of converted string in characters
result = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, (char *)bytes, 
    sizeof (bytes), NULL, 0);

wchar_t * name = new wchar_t [result];

// convert string
result = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, (char *)bytes, 
    sizeof (bytes), name, result);

关于c++ - 为什么 mbstowcs 返回 "invalid multibyte character",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6400597/

相关文章:

c++ - 在英特尔编译器中使用不同的标准 C++ 库 header

c++ - boost 正则表达式格式化程序,如何使用自定义函数

php - 如何使用 PHP 从上传到本地主机的一个 html 文件重定向到磁盘上的另一个 html 文件?

c - 合并排序没有给出正确的输出,c

c - 在 C 中有 char 指针时的 strcpy

r - 如何读取列名为 "Hebrew"的表(在 R 中)?

c++ - OLE DB批量复制操作始终将True装入位列

使用数组计算 5 个整数的平均值

c - 如何使用 C API 从 ICU4C UChar * 转换为 char *(以打印 Unicode 字符串)?

php - Wordpress DB 字符集从 utf8mb4 更改为 utf8 导致错误