数据类型为 unsigned char 时 scanf 行为的问题
A problem with the behaviour of scanf when data type is unsigned char
所以我不知道为什么会出现这种行为:
#include <stdio.h>
int main()
{
unsigned char c;
char d;
scanf("%hhu", &d);
printf("%c\n", d);
return 0;
}
如果我没记错的话 %hhu
是给 unsigned char
的。如果我输入几乎任何字符,如 a
或 b
,答案都是空的,d
得到值 0
。但是如果我输入 97
然后 d
打印值 a
(因此 ASCII 被转换为 char)。当数据类型为 char
时,情况显然不是这样。我直接输入字符就可以存储了
也在对这段代码稍加修改
#include <stdio.h>
int main()
{
unsigned char c;
char d;
int g;
scanf("%hhu", &d);
printf("%c\n", d);
scanf("%d", &g);
printf("%d is g\n", g);
return 0;
}
如果我将第一个输入作为 w
或 a
之类的字符,那么它只会跳过第二个 scanf
,但如果输入是数字,则它会正常工作。
格式说明符 %u
用于读取十进制整数,%hhu
是 %u
添加了长度修饰符。
要将一个字符读取到 char
变量,请使用说明符 %c
。
你是正确的,%hhu
格式说明符需要一个 unsigned char*
参数。但是,格式的 u
部分规定输入被解释为 十进制整数 。要将数据作为(未处理的)字符输入,您应该使用 %c
格式说明符。
If I input almost any character like 'a', or 'b' the answer is nothing and d gets the value 0. But if I input 97 then d prints the value a. (so ASCII is converted to char) This clearly not the case when the data type is char.
scanf
所做的与类型无关,而是与您使用的格式说明符相关(它又定义了参数中预期的类型)。
当您使用 %hhu
时,输入被读取为带符号的十进制 整数 ,按 strtoul
解析,并存储在 unsigned char
.这就是 97
被正确读取的原因。
此外,在这两个示例中,您应该考虑 return 值以了解是否有任何失败。这样你就可以检测错误并做任何需要的事情,比如再次询问用户。
If I remember correctly %hhu
is for unsigned char
. If I input almost any character like 'a', or 'b' the answer is nothing and d gets the value 0.
"%hhu"
期望输入文本是数字,如 "123"
。然后将123的值保存在d
中。 d
没有 得到 值 0。d
没有被 scanf("%hhu", &d);
更改,因为输入无效。
如果你想将一个字符读入 unsigned char
unsigned char d;
if (scanf("%c", &d) == 1) Success();
如果您想将数字文本读入 unsigned char
unsigned char d;
if (scanf("%hhu", &d) == 1) Success();
在所有情况下,测试 scanf()
的 return 值。
If I give first input as a character like 'w' or 'a' then it just skips the second scanf, but if the input is a number then it works normally.
当 scanf()
无法根据提供的说明符转换输入文本时,扫描将停止并且有问题的文本 仍然 在 stdin
.
中
一个常见的代码习惯用法是读取剩余的输入并将其扔到 '\n'
。
int ch;
while ((ch = getchar()) != '\n') && ch !- EOF) {
;
}
a
不是 %hhu
的有效输入。期望一个整数(在数学意义上)。如果我们添加错误检查(下面的代码),我们得到:
$ gcc -Wall -Wextra -pedantic a.c -o a && ./a
a
Number of assigned variables: 0
Can't read: Invalid input
#include <stdio.h>
#include <stdlib.h>
int main(void) {
unsigned char c;
int rv = scanf("%hhu", &c);
if (rv == EOF) {
if (ferror(stdin)) {
perror("Can't read");
} else {
fprintf(stderr, "Can't read: Premature EOF\n");
}
exit(1);
}
printf("Number of assigned variables: %d\n", rv);
if (rv < 1) {
fprintf(stderr, "Can't read: Invalid input\n");
exit(1);
}
printf("%hhu\n", c);
return 0;
}
无效输入保留在句柄的缓冲区中,以供将来读取。因此,早期 scanf
中的错误可能导致后来 scanf
失败。
如果您希望在出错后继续,您可以简单地阅读直到获得 LF 以清除缓冲区中的任何“垃圾”。
void read_stdin_to_eol(void) {
while (1) {
int ch = getchar();
if (ch == '\n' || ch == EOF)
return ch;
}
}
所以我不知道为什么会出现这种行为:
#include <stdio.h>
int main()
{
unsigned char c;
char d;
scanf("%hhu", &d);
printf("%c\n", d);
return 0;
}
如果我没记错的话 %hhu
是给 unsigned char
的。如果我输入几乎任何字符,如 a
或 b
,答案都是空的,d
得到值 0
。但是如果我输入 97
然后 d
打印值 a
(因此 ASCII 被转换为 char)。当数据类型为 char
时,情况显然不是这样。我直接输入字符就可以存储了
也在对这段代码稍加修改
#include <stdio.h>
int main()
{
unsigned char c;
char d;
int g;
scanf("%hhu", &d);
printf("%c\n", d);
scanf("%d", &g);
printf("%d is g\n", g);
return 0;
}
如果我将第一个输入作为 w
或 a
之类的字符,那么它只会跳过第二个 scanf
,但如果输入是数字,则它会正常工作。
格式说明符 %u
用于读取十进制整数,%hhu
是 %u
添加了长度修饰符。
要将一个字符读取到 char
变量,请使用说明符 %c
。
你是正确的,%hhu
格式说明符需要一个 unsigned char*
参数。但是,格式的 u
部分规定输入被解释为 十进制整数 。要将数据作为(未处理的)字符输入,您应该使用 %c
格式说明符。
If I input almost any character like 'a', or 'b' the answer is nothing and d gets the value 0. But if I input 97 then d prints the value a. (so ASCII is converted to char) This clearly not the case when the data type is char.
scanf
所做的与类型无关,而是与您使用的格式说明符相关(它又定义了参数中预期的类型)。
当您使用 %hhu
时,输入被读取为带符号的十进制 整数 ,按 strtoul
解析,并存储在 unsigned char
.这就是 97
被正确读取的原因。
此外,在这两个示例中,您应该考虑 return 值以了解是否有任何失败。这样你就可以检测错误并做任何需要的事情,比如再次询问用户。
If I remember correctly
%hhu
is forunsigned char
. If I input almost any character like 'a', or 'b' the answer is nothing and d gets the value 0.
"%hhu"
期望输入文本是数字,如 "123"
。然后将123的值保存在d
中。 d
没有 得到 值 0。d
没有被 scanf("%hhu", &d);
更改,因为输入无效。
如果你想将一个字符读入 unsigned char
unsigned char d;
if (scanf("%c", &d) == 1) Success();
如果您想将数字文本读入 unsigned char
unsigned char d;
if (scanf("%hhu", &d) == 1) Success();
在所有情况下,测试 scanf()
的 return 值。
If I give first input as a character like 'w' or 'a' then it just skips the second scanf, but if the input is a number then it works normally.
当 scanf()
无法根据提供的说明符转换输入文本时,扫描将停止并且有问题的文本 仍然 在 stdin
.
一个常见的代码习惯用法是读取剩余的输入并将其扔到 '\n'
。
int ch;
while ((ch = getchar()) != '\n') && ch !- EOF) {
;
}
a
不是 %hhu
的有效输入。期望一个整数(在数学意义上)。如果我们添加错误检查(下面的代码),我们得到:
$ gcc -Wall -Wextra -pedantic a.c -o a && ./a
a
Number of assigned variables: 0
Can't read: Invalid input
#include <stdio.h>
#include <stdlib.h>
int main(void) {
unsigned char c;
int rv = scanf("%hhu", &c);
if (rv == EOF) {
if (ferror(stdin)) {
perror("Can't read");
} else {
fprintf(stderr, "Can't read: Premature EOF\n");
}
exit(1);
}
printf("Number of assigned variables: %d\n", rv);
if (rv < 1) {
fprintf(stderr, "Can't read: Invalid input\n");
exit(1);
}
printf("%hhu\n", c);
return 0;
}
无效输入保留在句柄的缓冲区中,以供将来读取。因此,早期 scanf
中的错误可能导致后来 scanf
失败。
如果您希望在出错后继续,您可以简单地阅读直到获得 LF 以清除缓冲区中的任何“垃圾”。
void read_stdin_to_eol(void) {
while (1) {
int ch = getchar();
if (ch == '\n' || ch == EOF)
return ch;
}
}