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

C语言中write()/printf输出多字节非ASCII字符为何合并显示?

关于C语言输出多字节非ASCII字符的困惑

问题描述

尝试用C语言的write()或printf()输出ğ、ç、ş这类多字节非ASCII字符时,出现不符合预期的情况:

使用write()的代码

#include <unistd.h>

int main()
{
    char *str = "ğğğ";
    
    write(1, &str[0], 1);
    write(1, &str[1], 1);
}

预期输出单个ğ(因ğ占2字节,分两次输出两个字节),但实际仅显示一个ğ字符。

使用printf()的代码

#include <stdio.h>

int main()
{
    char *str = "ğğğ";
    
    printf("%c", str[0]);
    printf("%c", str[1]);
}

同样只打印出一个ğ字符,其他多字节字符也存在相同问题。

原因解析

核心原因是你的终端和字符串字面量采用的都是UTF-8编码:

  • 像ğ这类字符的UTF-8编码是双字节序列(0xC4 0x9F),终端会将连续的合法UTF-8字节序列解析为单个字符。
  • 当你第一次输出起始字节0xC4时,它属于UTF-8双字节字符的开头(高位为110开头),终端会进入等待状态,直到接收到第二个补全字节。
  • 第二次输出的0x9F补全了完整序列,终端才会将这两个字节组合起来渲染成一个ğ字符。
  • 你以为是两次输出操作,但终端是按完整的编码序列来处理显示的,所以最终看到的是一个完整字符,而非两个“半字符”。

对于printf("%c")的情况,本质和write一致:%c会输出单个字节,第一个字节输出后终端等待补全,第二个字节输出后才完成字符解析并显示。

验证方法

如果只保留第一次输出操作(注释掉第二次write或printf),终端不会显示任何字符,只会处于等待状态,直到输入补全字节或刷新缓冲区,这就能验证上述逻辑。

内容的提问来源于stack exchange,提问作者K.Ozbek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:55:11