You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C程序read函数可读取非ASCII字符,直接赋值汉字却失败?

终端字符编码与C程序读写的疑问解答

问题背景代码

代码1(正常运行)

int main (){

    int fd;
    fd = open("./dog.txt",O_RDONLY);
    //contents of dog.txt -> 漢è hello

    ssize_t r;
    char b;

    while( (r = read( fd, &b, sizeof(b))) > 0 ){
            
            write(STDOUT_FILENO,&b, sizeof(b));
            
    }

    printf("\n");

    //OUTPUT :  漢è hello
}

代码2(无法正常运行)

int main (){

  unsigned int test = '漢';

  write(STDOUT_FILENO,&test,sizeof(test));

  printf("\n");
}

核心问题解答

1. 终端如何知道需要将汉字解释为3字节的组合?

终端是按照**当前预设的字符编码(比如UTF-8)**解析字节流的。以UTF-8为例,它有明确的编码规则:

  • ASCII字符(0-127)用1字节表示,最高位为0
  • 非ASCII字符用多字节表示,首字节的前n位都是1,第n+1位是0,后续每个字节的前两位固定为10

当终端收到一个字节时,如果判断它是多字节字符的首字节(比如汉字“漢”的UTF-8首字节是0xE6,二进制为11100110,说明这是3字节字符),就会等待后续的2个字节,凑齐完整的编码单元后再解析成汉字,不会把单个字节当成独立字符处理。

2. 进程与终端之间是否存在某种协作机制来实现这一点?

没有特殊的协作机制,本质是双方遵循同一套字符编码规则。进程只负责把字节流写入终端(不管是逐个字节还是批量写入),终端则按照自身的编码设置(通常是UTF-8)解析这些字节。

唯一的要求是进程输出的字节编码要和终端设置匹配——如果进程输出GBK编码的字节,终端却设为UTF-8,就会出现乱码,但这只是规则匹配问题,不是进程和终端的主动协作。

3. 直白解释终端与C程序中的字符编码原理?

可以拆成两个层面理解:

  • C程序层面:read()/write()是纯字节级的读写操作,根本不关心字节代表什么字符。代码1能正常显示,是因为它把文件里的UTF-8原始字节原封不动地传给了终端,终端自己能正确解析这些字节。
    而代码2的问题在于:C语言中用单引号包裹的多字节字符(比如'漢')是“多字节字符常量”,它的值是编译器按源文件编码解析后生成的整数,不是UTF-8的字节序列。比如编译器用UTF-8的话,'漢'会被转换成0xE6BCA2这个整数,存储在4字节的unsigned int里后,write()会把这4字节(比如0xA2、0xBC、0xE6、0x00,取决于字节序)原样输出,这和终端需要的UTF-8字节序列(0xE6、0xBC、0xA2)完全不符,所以无法显示正确的汉字。
  • 终端层面:终端是一个“字节流解析器”,按照预设的编码规则把连续字节转换成对应字符显示。只要字节流符合编码规则,不管是一次性收到还是分多次收到,终端都会自动拼接、解析成正确的字符。

内容的提问来源于stack exchange,提问作者user18503064

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 18:01:18