我目前正在编写一个 C 程序,我需要从键盘读取一个多字节字符。我想输入一个两字节字符(例如“ą”)并确保不能输入多个字符。此外,我想处理尝试输入多字节字符导致错误的情况。
如果可能,请提供一个简单的 C 语言代码示例。 ;)
我尝试使用 getchar() 读取输入,然后检查缓冲区是否与换行符不同: getchar() != ' '。不幸的是,这不允许我在输入中输入像“ą”这样的字符,可能是因为缓冲区中残留着一些东西。
从问题中尚不清楚您真正想要什么,以及为什么防止用户输入多个字节或多个字符有帮助。所以我的答案集中在检测多字节字符上。您正在 macOS 终端(或 macOS 上的类似终端)中运行您的程序。它使用 UTF-8 编码(字符集),其中 ASCII 字符(代码 0..127)是单字节,其他所有字符都是多字节。
这是一个 C 程序,它计算并打印每行的标准输入上的字节数和 Unicode 字符数。它可以在 macOS 的终端窗口中运行。 (它也适用于大多数 Linux 系统,因为就像在 macOS 上一样,默认编码是 UTF-8。它不适用于 Windows,因为 Windows 上的许多终端程序不使用 UTF-8。)
#include <stdio.h>
int main(int argc, char **argv) {
unsigned bc = 0, cc = 0, lc = 0;
int c;
(void)argc; (void)argv;
while ((c = getchar()) != EOF) {
if (c == '\n') {
++lc;
printf("bytes=%u characters=%u lines=%u\n", bc, cc, lc);
bc = cc = 0;
}
++bc;
if ((c & 0xc0) != 0x80) ++cc;
}
return 0;
}
计算多字节字符的有趣行是:
if ((c & 0xc0) != 0x80) ++cc;
C 函数调用
c = getchar()
返回 1 个字节(不是字符!)或 EOF。获取无符号字节值 (0 .. 255),使用 c & 0xff
.
在 UTF-8 编码中,多字节字符以前导字节开始,并以 1 个或多个连续字节继续。前导字节的位模式为 11?????? (
(c & 0xc0) == 0xc0
),连续字节的位模式为 10?????? ((c & 0xc0) == 0x80
).
您可以使用上面的代码片段来检测多字节字符,然后在遇到时让程序退出并显示错误消息。您还可以使用上面的代码来检测多个字符(或多个字节),然后让您的程序退出并显示错误消息(如果遇到)。
如果你想编写一个更智能的程序,可以处理多字节字符,那么你有两个选择: 1. 将每个字符视为一个字节序列; 2. 首先将每个输入行转换为字符序列(例如
uint32_t
的数组),然后对该数组运行算法。