我需要将通用字符名称(UCN)数据从数据库转换为UTF-8.看似微不足道,但我花了几个小时阅读有关Unicode、UTF-8、宽字符串等方面的内容.没有任何结果.

例如,需要将以下字符串从D\u00c3\u00bcsseldorf转换为Düsseldorf.

我try 了什么:

char str[] = "\u00c3\u00bc"; // corresponds to ü
size_t str_len = strlen(str);
for (i = 0; i < str_len; i++)
    printf("%02hhx ", str[i]);
printf("- %zu - %s\n", str_len, str); // prints "c3 83 c2 bc - 4 - ü"

c3 is correct, but the next 3 bytes are unexpected.
The compiler only considers the first part of the UCN (\u00c3).

wchar_t wcs[] = L"\u00c3\u00bc";
size_t wcs_len = wcslen(wcs);
for (i = 0; i < wcs_len; i++)
    printf("%02hhx ", wcs[i]);
printf("- %zu - %ls\n", wcs_len, wcs); // prints "c3 bc - 2 - ü"

Looks better.
The entire UCN is considered (c3 bc), but still no ü.

char str[] = "\xc3\xbc";
size_t str_len = strlen(str);
for (i = 0; i < str_len; i++)
    printf("%02hhx ", str[i]);
printf("- %zu %s\n", str_len, str); // prints "c3 bc - 2 ü"

这会打印ü,但我将str从UCN修改为十六进制代码.

\u00c3\u00bc分到ü分,我错过了什么?

推荐答案

char str[] = "\u00c3\u00bc"; // corresponds to ü

这就是你错的地方.这不是ü.这是ü,就像正在输出的一样.

ü的UCN是\u00fc:LATIN SMALL LETTER U WITH DIAERESIS

$ uni print c3 bc
     CPoint  Dec    UTF8        HTML       Name (Cat)
'¼'  U+00BC  188    c2 bc       &frac14;   VULGAR FRACTION ONE QUARTER (Other_Number)
'Ã'  U+00C3  195    c3 83       &Atilde;   LATIN CAPITAL LETTER A WITH TILDE (Uppercase_Letter)

$ uni id ü
     CPoint  Dec    UTF8        HTML       Name (Cat)
'ü'  U+00FC  252    c3 bc       &uuml;     LATIN SMALL LETTER U WITH DIAERESIS (Lowercase_Letter)

Unicode代码点(UCN编码) for each Unicode字符分配一个数字.它们是字符的标识符,而不是编码.

您在这里编写的是ü的UTF-8编码.UTF-8是一种写下Unicode代码点的方式.除ASCII值(0-127)外,UTF-8字节始终与码位的值大不相同.(UTF-8可能是有史以来设计的最聪明、最有用的文本编码.But it is not trivial to understand.)

如果您想要手动编码UTF-8,那么\x语法是正确的.您可以通过这种方式将任意字节注入C字符串.但是,通常情况下,在表示字符时,您应该更喜欢\u00fc语法.

您的第一个字节看起来是正确的,原因是UTF-8编码是c383."c3"是许多修改后的拉丁字符的UTF-8编码的第一个字节.查看大量c3字节是检测西欧UTF-8文本的一种简单方法.

C++相关问答推荐

为什么静态说明符为内联函数生成外部定义?

无效使用未定义类型'structsquare'?

为什么删除CAP_DAC_OVERRIDE后创建文件失败?

有没有可能我不能打印?(C,流程)

在C23中使用_GENERIC实现带有右值的IS_POINTER(P)?

Linux不想运行编译后的文件

在Rust和C之间使用ffi时如何通过 struct 中的[U8;1]成员传递指针

防止C++中递归函数使用堆栈内存

用C++实现余弦函数

无法访问共享目标文件内的共享指针

按长度对argv中的单词进行排序

C语言中MPI发送接收字符串时出现的分段错误

将回调/基于事件的C API转换为非回调API

使用正则表达式获取字符串中标记的开始和结束

如何编写postgresql支持函数

C程序printf在getchar while循环后不工作

C中2个数字的加法 - 简单的人类方法

GDB 跳过动态加载器代码

使用复合文字数组初始化的指针数组

OpenGL 中的非渐变 colored颜色 变化