为何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
相关产品推荐
相关产品推荐

