ᛉᛉᛉ*_*ᛉᛉᛉ 5 c string unicode parsing
我的想法是用 C 语言编写一个类似 Hangman 的游戏。我希望它能够使用带有元音变音的德语单词(例如:\xc3\xa4, \xc3\xbc, \xc3\xb6)以及希腊单词(完全非 ASCII 字符)。
我的编译器和终端可以很好地处理 Unicode。显示字符串效果很好。
\n但是我应该如何对这些字符串进行操作呢?对于德语,我也许可以通过在函数中处理这些大小写来处理 6 个大写和小写重音字符。但考虑到希腊语,这似乎是不可能的。
\n我写了这个测试代码。它输出字符串、字符串的长度(当然是错误的,因为 UTF-8 序列代替了两个字符)以及字符串中各个字符的纯文本和十六进制值。
\n#include <stdio.h>\n#include <string.h>\n\nint main() {\n printf("123456789\\n");\n char aTestString[] = "cheese";\n printf("%s ist %d Zeichen lang\\n", aTestString, strlen(aTestString));\n \n for (int i = 0; i < strlen(aTestString); i++) {\n printf("( %c )", aTestString[i]); // char als char\n printf("[ %02X ]", aTestString[i]); // char in hexadezimal\n }\n\n printf("\\n123456789\\n");\n char aTestString2[] = "K\xc3\xa4se";\n printf("%s has %d characters\\n", aTestString2, strlen(aTestString2));\n \n for (int i = 0; i < strlen(aTestString2); i++) {\n printf("( %c )", aTestString2[i]); // char als char\n printf("[ %02X ]", aTestString2[i]); // char in hexadezimal\n }\n \n printf("\\n123456789\\n"); \n char aTestString3[] = "\xce\xbb\xcf\x8c\xce\xb3\xce\xbf\xcf\x82";\n printf("%s has %d characters\\n", aTestString3, strlen(aTestString3));\n\n for (int i = 0; i < strlen(aTestString3); i++) {\n printf("( %c )", aTestString3[i]); // char als char\n printf("[ %02X ]", aTestString3[i]); // char in hexadezimal\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n例如,推荐的方法来计算 Unicode 字符,或者查看字符串中是否存在特定的 Unicode 字符(即代码点)?我确信必须有一些简单的解决方案,因为这些字符经常在密码中使用。
\n这是测试程序的输出:
\n123456789\ncheese has 6 character\n( c )[ 63 ]( h )[ 68 ]( e )[ 65 ]( e )[ 65 ]( s )[ 73 ]( e )[ 65 ]\n123456789\nK\xc3\xa4se has 5 characters\n( K )[ 4B ]( )[ FFFFFFC3 ]( )[ FFFFFFA4 ]( s )[ 73 ]( e )[ 65 ]\n123456789\n\xce\xbb\xcf\x8c\xce\xb3\xce\xbf\xcf\x82 has 10 characters\n( )[ FFFFFFCE ]( )[ FFFFFFBB ]( )[ FFFFFFCF ]( )[ FFFFFF8C ]( )[ FFFFFFCE ]( )[ FFFFFFB3 ]( )[ FFFFFFCE ]( )[ FFFFFFBF ]( )[ FFFFFFCF ]( )[ FFFFFF82 ]\nRun Code Online (Sandbox Code Playgroud)\n
C 的多字节字符串实用程序在这种情况下很有用。mbrlen例如,使用 来查找字符串中的字符数的一种方法(尽管这可能是我现在刚刚拼凑在一起的一种非常天真的方法)是这样的:
#include <stdio.h>\n#include <wchar.h>\n#include <locale.h>\n\nsize_t string_size(const char *s)\n{\n mbstate_t state = {0};\n size_t len = 0;\n for (; *s != \'\\0\'; ++len)\n {\n unsigned c_len;\n for (c_len = 1; mbrlen(s+c_len-1, 1, &state) == -2; ++c_len) {}\n s += c_len;\n }\n return len;\n}\n\nint main(void)\n{\n setlocale(LC_ALL, "en_US.utf8");\n const char *s = "z\xc3\x9f\xe6\xb0\xb4";\n printf("%zu\\n", string_size(s));\n}\n\n// Output: 4\nRun Code Online (Sandbox Code Playgroud)\n使用相同的函数mbrlen,您还可以通过查找字符的长度来提取单个字符。如果您想使用多字节字符和宽字符,还有一些函数可以在多字节字符和宽字符之间进行转换。