如何在C ++中打印字符串中的转义十六进制?

时间:2013-05-26 04:53:07

标签: unicode hex

我有与Unicode相关的问题,在const char*打印转义的十六进制值。

  1. 根据我的理解,utf-8包括2字节,3字节或4字节字符,范围从英镑符号到汉字字符。在字符串中,这些以十六进制值表示,使用\ u作为转义序列。我也理解在字符串中使用十六进制转义时,将包含其值可以包含在转义中的字符。例如,说“abc \ x0f0dab”将包含0f0dab,在\ x中被视为十六进制,即使您只想要考虑0f0d。
  2. 现在在编写Unicode字符串时,假设您要编写“abcdef₤ghi”,其中Unicode为0x24B62且₤为0x00A3。所以我将把字符串组成“abc0x24B62def0x00A3ghi”。 0x将考虑可以包含在其中的所有值。因此,如果要打印“abc62”,字符串将为“abc0x24B6262”。整个字符串不会被视为在0x内考虑的4字节unicode(0x24B6262)值吗?怎么解决这个?如何打印“abc62”而不是abc(0x24B6262)?

    1. 我有一个字符串const char* tmp = "abc\x0fdef";。当我使用printf("\n string = %s", tmp);打印时,它将打印abcdef。 0f在哪里?我知道\ x0f的十进制值将存储在字符串中,即15,所以当我们尝试打印时,应该打印15?我的意思是,它应该是“abc15def”,但它只打印“abcdef”。

1 个答案:

答案 0 :(得分:2)

我认为你可能不熟悉编码的概念,从阅读你的帖子。

例如,你说“un的unicode是0x00A3”。这是真的 - unicode代码点U + 00A3是英镑符号。但0x00A3并不是你如何表示英镑符号,例如,UTF-8(Unicode的一种特殊常见编码)。拿一个look here来看看我的意思。如您所见,U + 00A3的UTF-8编码是两个字节0xc20xa3(按此顺序)。

在致电printf()和屏幕上显示某些内容之间,有几件事情发生。

首先,您的程序运行代码printf("abc\x0fdef"),这意味着按顺序将以下字节写入您的程序的stdout:

0x61, 0x62, 0x63, 0x0f, 0x64, 0x65, 0x66

注意:我假设你的源代码是ASCII(或UTF-8),这很常见。从技术上讲,我相信对源代码字符集的解释是实现定义的。

现在,为了查看输出,您通常会在某种shell中运行此程序,并且最终必须将这些字节转换为可视字符。它通过使用编码来实现。同样,ASCII兼容的东西很常见,例如UTF-8。在Windows上,CP1252很常见。

如果是这种情况,您将获得以下映射:

0x61 - a
0x62 - b 
0x63 - c
0x0f - the 'shift in' ASCII control code
0x64 - d
0x65 - e
0x66 - f

这打印为“abcdef”,因为'shift in'控制代码是非打印字符。

注意:上述内容可能会根据所涉及的确切字符集而改变,但除非您有异国情调的设置,否则您正在处理的是ASCII或UTF-8。

如果您有兼容UTF-8的终端,以下内容应打印出“abc₤def”,这只是为了让您入门:

printf("abc\xc2\xa3def");

有意义吗?


更新:要回答评论中的问题:您需要区分 codepoint 编码的字节值码点。

Unicode标准定义了“代码点”,它们是字符的数值。这些通常写为U + XYZ,其中XYZ是十六进制值。 例如,字符U + 219e是LEFTWARDS TWO HEADED ARROW。 这也可能写成0x219e。你会从上下文中知道作者正在谈论一个代码点。

当您需要对该代码点进行编码(打印或保存到文件等)时,您使用编码,例如UTF-8。请注意,如果您使用了UTF-32编码,则每个代码点都与编码值完全对应。因此在UTF-32中,代码点U + 219e确实将被编码为0x219e。但其他编码将以不同的方式做事。 UTF-8将U + 219e编码为三个字节0xE2 0x86 0x9E

最后,\x表示法只是在C / C ++引用字符串中编写任意字节值的方式。如果我用C源代码编写"\xff",那么内存中的那个字符串将是两个字节0xff 0x00(因为它会自动获得一个空终止符)。