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

为何printf无法输出ASCII字符表中开头为'2'的行首字符?

ASCII表行首字符缺失问题修复

我想要打印如下格式的ASCII字符表:

0 1 2 3 4 5 6 7 8 9 a b c d e f
0 
1            
2   ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ \ ] ^ _
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { | } ~ 
8 � � � � � � � � � � � � � � � �
9 � � � � � � � � � � � � � � � �
a � � � � � � � � � � � � � � � �
b � � � � � � � � � � � � � � � �
c � � � � � � � � � � � � � � � �
d � � � � � � � � � � � � � � � �
e � � � � � � � � � � � � � � � �
f � � � � � � � � � � � � � � � �

编写了如下C语言代码:

#include <stdio.h>

int main() {
    char s[34] = "  0 1 2 3 4 5 6 7 8 9 a b c d e f\n";
    printf("%s", s);
    for (size_t i = 0; i < 16; ++i) {
        char str[34];
        char hex[2];
        snprintf(hex, sizeof(hex), "%x", (int)i);
        str[0] = hex[0];
        for (size_t j = 0; j < 16; ++j) {
            str[2 * j + 1] = ' ';
            str[2 * j + 2] = i * 16 + j;
        }
        str[33] = '\0';
        printf("%s\n", str);
    }
}

但程序输出如下:

0 1 2 3 4 5 6 7 8 9 a b c d e f
0 
1            
   ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ \ ] ^ _
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { | } ~ 
8 � � � � � � � � � � � � � � � �
9 � � � � � � � � � � � � � � � �
a � � � � � � � � � � � � � � � �
b � � � � � � � � � � � � � � � �
c � � � � � � � � � � � � � � � �
d � � � � � � � � � � � � � � � �
e � � � � � � � � � � � � � � � �
f � � � � � � � � � � � � � � � �

问题:原本应以'2'开头的行,输出时缺失了行首的'2'。


问题原因

问题出在控制字符的输出干扰了终端光标位置:

  • 当i=0和i=1时,行内的字符是ASCII控制字符(0-31),比如退格(\b,ASCII 8)、换行(\n,ASCII 10)、制表符(\t,ASCII 9)等。
  • 这些控制字符不会被终端显示为可见字符,反而会执行光标移动、换行等操作,导致后续行的输出位置错乱,最终i=2行的行首字符'2'被终端的光标操作覆盖或跳过。

修复方案

修改代码,将控制字符替换为可见占位符(比如空格),避免终端执行控制操作:

#include <stdio.h>
#include <ctype.h> // 包含isprint函数

int main() {
    char s[34] = "  0 1 2 3 4 5 6 7 8 9 a b c d e f\n";
    printf("%s", s);
    for (size_t i = 0; i < 16; ++i) {
        char str[34];
        char hex[2];
        snprintf(hex, sizeof(hex), "%x", (int)i);
        str[0] = hex[0];
        for (size_t j = 0; j < 16; ++j) {
            str[2 * j + 1] = ' ';
            unsigned char c = i * 16 + j;
            // 仅输出可打印字符,控制字符替换为空格
            str[2 * j + 2] = isprint(c) ? c : ' ';
        }
        str[33] = '\0';
        printf("%s\n", str);
    }
}

修复效果

修改后,控制字符会被替换为空格,终端输出不再被干扰,i=2行的行首'2'正常显示,输出符合预期:

0 1 2 3 4 5 6 7 8 9 a b c d e f
0                                
1                                
2   ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ \ ] ^ _
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { | } ~ 
8                                
9                                
a                                
b                                
c                                
d                                
e                                
f                                

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:05:09