众所周知,如果我们在 ac 源文件中编写类似 "\x61\x61" 的字符串,它实际上表示 "aa"。当从控制台为 getc 或 fgetc 的功能输入一个字符时,无论如何我们只给出一些十六进制值?也许像 '\x61' 但不是 'a'。
1 回答
简短的总结是没有。但你可能想要的远不止这些。
假设您的环境正在使用 ASCII 的某些超集(虽然语言不需要,但对于本世纪的任何机器和操作系统来说,这是一个非常合理的假设),"\x61\x61"
是 "aa"
. 转换是在编译时完成的——如果你检查编译器的输出(例如,通过阅读它发出的汇编代码),你会aa
在那里找到,而不是\x61\x61
. 允许这种语法是为了让人们在代码文件中编写否则将无效的字符(最流行的示例是代码点零,写入\x00
或\000
基本上总是缩写为\0
(只要它后面没有数字 0- 7 范围))。
这里的关键点是您的程序看不到\x61\x61
,而是aa
. 您无法恢复源表示 - 就像您无法分辨24
,030
和0x18
分开一样。
另一方面,getc
和朋友阅读原始文本输入。除了换行符转换之外,它们不进行任何处理。如果要进行处理,则必须在自己的代码中进行。这样的处理还必须处理无效序列(例如\xyz
)以及调整大小和移动字符串(因为\x61
是四个字符并且a
是一个),这些问题并不像乍一看那么明显。将这种负担强加给需要这种特定处理的奇数应用程序的所有应用程序是不正确的。
如果您知道要读取十六进制转义序列(而不是直字符),那么您可以使用以下命令读取十六进制输入scanf
:
unsigned char next;
int rv = scanf("\\x%2hhx", &next);
// now rv is true if a character was read, and next contains the character
但是,这种方法不适用于混合在转义序列中的字符串,例如x\x79z
. 对于这些字符串,您必须编写一个实际的字符串处理器来转换它们——就像编译器对您的代码所做的那样。