【问题标题】:Printing a particular hexadecimal value in character representation以字符表示形式打印特定的十六进制值
【发布时间】:2018-01-31 21:17:28
【问题描述】:

当尝试在字符串中使用 '\x05' 时,编译后的 C 代码在处理该值时似乎表现异常。

例如使用以下字符串时:

char *weird = "\x04\x68\x65\x79\x79\x03\x6e\x65\x74\x05\x6c\x6f\x63\x61\x6c\x00";

打印字符串的每个字符时,'\x05'不对应整数5,而'\x04''\x03'分别对应整数4和3。

下面的for循环演示了这个问题:

for(int i = 0; i < strlen(question); i++){
    printf("question[%d] = %c\n", i, question[i]);
}

输出:

知道为什么'\x05' 的这个具体案例如此麻烦吗?

【问题讨论】:

  • 它表现得很好。 3 和 4 不对应任何整数。你的字体就是这样显示的。
  • 您要打印字符“5”吗?如果是这样, '\x05' 不是你要找的。 '5' 的 ASCII 码是 '\x35'。
  • 0x03ETX(文本结束),0x04EOT(传输结束),0x05ENQ(查询)。这些不是可打印的字符,而是control characters
  • “是”和“不是”可打印取决于 OP 的终端旨在处理什么。显然,在 OP 的角色中,他们——他们是否应该是另外一回事。我认为显示某些内容是为了方便,而不是“什么都没有”——或者整个系统崩溃。
  • 提示:要使打印的内容更加清晰,请用标记字符包围 --> printf("question[%d] = [%c]\n", i, question[i]); 添加[]。也许'\0x05' 正在打印一个空格?更好的是,试试for(int i = 0; i &lt;= 48; i++) { printf("%2d = [%c]\n", i, i); }

标签: c printf control-characters


【解决方案1】:

%c 格式说明符用于作为参数提供的相应整数值的可打印字符表示。根据 ASCII 编码,0x030x040x05 都不是可打印值!!

为了确认起见,您可以在尝试打印之前将相同的值传递给 isprint()。如果您选择打印它,“显示”最终取决于您的终端选择如何解释显示。

这里有一些参考资料(12)列出了可打印和不可打印的 ASCII 值

【讨论】:

  • 但是 OP 的输出证明 3 和 4 可打印的。
  • @usr2564301 不,我不会这么说。 :)
  • @usr2564301 这显然不是真的。
  • @usr2564301 他们可能是可打印的。
  • 好吧,假设 ASCII 没有定义如何这些是可打印的。
【解决方案2】:

你的假设是错误的。 ASCII 代码 3、4 和 5对应于(可见的)整数 345

您看到的是本地终端对它认为您要打印的内容的翻译

  1. 它不会尝试解释代码34。这些对应于 ASCII 控制字符 End of TextEnd of Transmission,但您的终端选择不处理它们。因此,它将这两个代码逐字写入输出流,输出流查找合适的字体来显示它们。在现代 (Unicode) 字体中,这些字符没有字符,因为它们不应该被“打印”。但是,一些终端会意识到这一点,并提供了一个备用功能,因此您至少可以看到一些东西。

  2. 另一方面,代码5由您的终端解释:“信号旨在触发接收端的响应,看看它是否仍然存在。 "终端发送该信号,接收(很可能)一个“是”的回答——是的,输出流处于活动状态——并继续输出文本的其余部分。因为它是一个信号而不是一个字符,所以什么都不显示。

这种行为对于0x05 代码并不是唯一的。你没有在你的问题中提到它,但是当你“打印”\n'时,你似乎并不惊讶于得到一个新行,即使它将代码0x0A 发送到输出流。你确实不会在屏幕上看到10,但光标会向下移动一行。同样,这是因为该代码被终端解释为采取某些特定操作。

【讨论】:

    【解决方案3】:

    完全没问题。 \x05 不是 ASCII 表中的可打印字符,这就是您看到奇怪字符的原因。

    %c 需要可打印字符,而您不是。

    List of printable ASCII characters

    【讨论】:

    • %c 需要 int(在可变参数函数中提升),但它是操作系统决定它是否可打印。
    • @WeatherVane 更加迂腐 - 是终端在发号施令。
    • @EugeneSh。终端由操作系统实现。
    • @WeatherVane 不一定。您可以有一个裸机 C 项目通过串行端口将这些发送到某个串行终端,模拟任何标准(VT100、VT50、一些自定义,您可以命名)
    猜你喜欢
    • 2016-04-17
    • 2014-03-09
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多