我已经使用intl.cpl
将终端编码更改为UTF-8,并将系统区域设置更改为UTF-8。但是,我仍然无法输入UTF-8字符,例如å
。如果我输入chcp
,则输出为:
Active code page: 65001
字符串
这表明UTF-8是“激活的”。
那么,为什么这段代码不起作用:
#include <stdio.h>
int main(void) {
char myChar;
printf("Enter the letter å: ");
scanf("%c", &myChar);
printf("Entered letter: %c", myChar);
return 0;
}
型
输入为å
。
输出为:
Enter the letter å: å
Entered letter:
型
为什么会发生这种情况?这真的很令人沮丧,我真的很感激一些帮助。- 谢谢-谢谢
3条答案
按热度按时间vsikbqxv1#
C程序的默认区域设置是C。将区域设置切换到您设置的用户区域设置。
UTF-8中的
å
需要 * 两个 * 字节。它不适合一个char
。使用宽字符。字符串
3bygqnnd2#
为什么会发生这种情况?
因为在UTF-8中,
å
被编码为多字节序列。您只阅读和回显第一个字节。多字节字符不能存储在单个char
中,也不能由单个char
表示.这差不多就是“多字节”的定义。这里的一个关键问题是一些不匹配的术语。在大多数情况下,C语言规范和标准库文档使用术语“字符”,非限定的,他们意味着一个
char
大小的二进制数。也就是说,粗略地说,一个字节。但是,Unicode规范中的“字符”是非限定的,它们通常是指 * 抽象 * 字符。你不能在这个意义上触摸人物。你可以触摸到的是Unicode所称的 * 编码字符 *,它通过 * 代码单元 * 的序列根据特定的 * 编码形式 * 表示抽象字符的Unicode * 字符代码 *。UTF-8是一种Unicode编码形式,具有由8位代码单元组成的可变长度代码序列。
当你说你想输入一个“Unicode字符”时,你的意思似乎是你想输入一个完整的代码序列,对于UTF-8,它可能是从一个到四个字节的任何地方(而对于UTF-16,它可能是一个或两个16位单位)。在C中,最透明的方法是输入到C字符串中,并从C字符串中输出。举例来说:
字符串
但是,请注意,尽管这肯定会读取至少一个UTF-8编码的字符,但如果用户输入多个字符,它可能会读取多个字符(但可能少于两个)。
总的来说,如果您可以忽略特定的编码形式(但假设它使用一个字节的代码单元),那么将其全部视为字符串是一个很好的策略。如果您只需要读取、存储和回显提供给程序的字符数据,则会出现这种情况。
另一方面,如果您需要执行任何编码感知的操作,或者希望更干净地处理具有不同大小代码单元的编码,或者执行其他各种Unicode感知的活动,则可能应该使用专门用于处理这些操作的库。例如,ICU是一个受欢迎且得到很好支持的版本,我个人在使用它时取得了很大的成功。
kuarbcqp3#
这是不可能的爱或金钱读取UTF-8字符从Windows终端使用Microsoft C运行时库又名
msvcrt
。你试图做错了,这在其他答案中有详细说明,但即使你做对了,也就是说。以在所有其他系统上都能工作的方式,它仍然不能在使用msvcrt
的Windows上工作。您的选项包括:
cygwin
orucrt