如何从控制台为 getc 输入十六进制值
How to make a Hexadecimal value input from the console for getc
我们知道,如果我们在c源文件中编写类似“\x61\x61”的字符串,它实际上表示“aa”。当从控制台为 getc 或 fgetc 的功能输入一个字符时,我们是否只是给出一些十六进制值?可能像 '\x61' 但不是 'a'.
简短的总结是没有。但您可能想要的不止于此。
假设您的环境正在使用 ASCII 的一些超集(虽然语言不需要,但对于本世纪以来的任何机器和 OS 来说都是一个相当合理的假设),"\x61\x61"
是"aa"
。转换是在编译时完成的——如果您检查编译器的输出(例如,通过阅读它发出的汇编代码),您会在其中找到 aa
,而不是 \x61\x61
。允许使用此语法是为了让人们编写在代码文件中无效的字符(最流行的示例是代码点零,写为 \x00
或 [=16=]0
并且基本上总是缩写为 [=17= ]
(只要后面没有跟在 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
。对于这些字符串,您必须编写一个实际的字符串处理器来转换它们——就像编译器对您的代码所做的那样。
我们知道,如果我们在c源文件中编写类似“\x61\x61”的字符串,它实际上表示“aa”。当从控制台为 getc 或 fgetc 的功能输入一个字符时,我们是否只是给出一些十六进制值?可能像 '\x61' 但不是 'a'.
简短的总结是没有。但您可能想要的不止于此。
假设您的环境正在使用 ASCII 的一些超集(虽然语言不需要,但对于本世纪以来的任何机器和 OS 来说都是一个相当合理的假设),"\x61\x61"
是"aa"
。转换是在编译时完成的——如果您检查编译器的输出(例如,通过阅读它发出的汇编代码),您会在其中找到 aa
,而不是 \x61\x61
。允许使用此语法是为了让人们编写在代码文件中无效的字符(最流行的示例是代码点零,写为 \x00
或 [=16=]0
并且基本上总是缩写为 [=17= ]
(只要后面没有跟在 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
。对于这些字符串,您必须编写一个实际的字符串处理器来转换它们——就像编译器对您的代码所做的那样。