C 用户仅输入整数,来自 scanf 的 return 值
C user input only integers, return value from scanf
我正在尝试获取一些用户输入,我想确保他们输入的是整数,如果他们不输入,我会要求他们再次输入(循环直到他们输入正确)。
我发现了很多不同的方法来做到这一点;有些比其他的更复杂。但我发现这种方法似乎有效。
但我真的不明白为什么要在代码中测试它:
scanf("%d%c", &num, &term) != 2
我能理解scanf
输出匹配分配成功的项目数,但我不明白为什么它输出2如果它是一个整数。
C 中的代码是:
int main(void)
{
int num;
char term;
if (scanf("%d%c", &num, &term) != 2 || term != '\n')
printf("failure\n");
else
printf("valid integer followed by enter key\n");
}
试图将其放入循环中:
int main(void){
int m, n, dis;
char m_check, n_check, dis_check;
do{
m = 0; n = 0; dis = 0;
m_check = ' '; n_check = ' '; dis_check = ' ';
printf("Please enter number of rows m in the matrix (integer): ");
if(scanf("%d%c", &m, &m_check) !=2 || m_check != '\n')
m_check = 'F';
printf("Please enter number of columns n in the matrix (integer): ");
if(scanf("%d%c", &n, &n_check) !=2 || n_check != '\n')
n_check = 'F';
printf("Should the random numbers come from a uniform or normal distribution?...
Please press 1 for uniform or 2 for normal: ");
if(scanf("%d%c", &dis, &dis_check) !=2 || dis_check != '\n' || dis != 1 || dis !=2)
dis_check = 'F';
}while(m_check == 'F' || n_check == 'F' || dis_check == 'F');
我试过只输入 m = 3、n = 3、dis = 2,然后循环重新开始并要求我输入行数。如果我被要求按 f 或其他东西,它就会开始疯狂地循环打印 printf 语句 :)
scanf
returns 它转换的字段数。您有格式字符串 %d%c
;它有:
%d
- 第一个字段
%c
- 第二个字段
所以scanf
returns 2.
如果用户输入数字,例如123
并按 Enter,您的 num
将等于 123
,而 term
将等于 \n
。
如果用户输入的数字末尾有乱码,例如123garbage
并按 Enter,您的 num
将等于 123
,term
将等于 g
,并且arbage\n
将保留在输入缓冲区中。
在这两种情况下,scanf
读取一个 int
和一个 char
,所以它 returns 2.
另一个例子:用户输入 garbage123
。在这种情况下,scanf
将无法读取整数,而 return 0.
因此您的代码会检查两种不同形式的错误输出。
scanf("%d%c", &num, &term) != 2
这会检查 scanf
的 return
值。它将正确匹配 return
个参数。因此,如果输入 integer
和字符,它们将存储在变量 num
和 term
和 scanf
returns
2
中。
如果两个参数都没有正确匹配,scanf
将不会 return
2
,在这种情况下,failure
将显示为输出。
输入一个整数将匹配格式化程序 %d
,并将值赋给变量 num
。 %c
格式化程序将采用换行符 ('\n') 并将其存储在变量 term
中。 scanf
returns 2 导致正确分配的 2 个元素(num
和 term
)
如果您不输入整数,格式化程序 %d
将无法正确匹配,scanf
也不会 return 2,产生失败
编辑:您的 do-while 循环变得疯狂,因为您在上次 scanf 中的条件是错误的 (dis != 1 || dis !=2
)。应该是
if(scanf("%d%c", &dis, &dis_check) !=2 || dis_check != '\n' || (dis != 1 && dis !=2))
糟糕 - 现在看到 OP 想知道为什么接近失败并且不一定在寻找操作方法。将其作为参考,因为它确实断言了基本问题:scanf()
。不要将其用于 user 输入。
如果代码确实需要 "get some user input, and wants to make sure that they enter integers",则使用 fgets()
获取行并 然后 处理输入。
将用户输入与 scanning/parse 混合使用总是会导致某些用户输入无法通过检查、stdin
中的额外用户输入或不正确地等待更多输入。
// true implies success
bool Read_int(int *value) {
char buffer[100];
if (fgets(buffer, sizeof buffer, stdin) == NULL) return false; // EOF or error
// Now parse the input
char *endptr;
errno = 0;
long number = strtol(buffer, &endptr, 10);
if (errno) return false; // long overflow
if (number < INT_MIN || number > INT_MAX) return false; // int overflow
if (endptr == buffer) return false; // No conversion
while (isspace((unsigned char) *endptr)) endptr++;
if (*endptr) return false; // non-white-space after number
*value = (int) number;
return true;
}
我正在尝试获取一些用户输入,我想确保他们输入的是整数,如果他们不输入,我会要求他们再次输入(循环直到他们输入正确)。
我发现了很多不同的方法来做到这一点;有些比其他的更复杂。但我发现这种方法似乎有效。
但我真的不明白为什么要在代码中测试它:
scanf("%d%c", &num, &term) != 2
我能理解scanf
输出匹配分配成功的项目数,但我不明白为什么它输出2如果它是一个整数。
C 中的代码是:
int main(void)
{
int num;
char term;
if (scanf("%d%c", &num, &term) != 2 || term != '\n')
printf("failure\n");
else
printf("valid integer followed by enter key\n");
}
试图将其放入循环中:
int main(void){
int m, n, dis;
char m_check, n_check, dis_check;
do{
m = 0; n = 0; dis = 0;
m_check = ' '; n_check = ' '; dis_check = ' ';
printf("Please enter number of rows m in the matrix (integer): ");
if(scanf("%d%c", &m, &m_check) !=2 || m_check != '\n')
m_check = 'F';
printf("Please enter number of columns n in the matrix (integer): ");
if(scanf("%d%c", &n, &n_check) !=2 || n_check != '\n')
n_check = 'F';
printf("Should the random numbers come from a uniform or normal distribution?...
Please press 1 for uniform or 2 for normal: ");
if(scanf("%d%c", &dis, &dis_check) !=2 || dis_check != '\n' || dis != 1 || dis !=2)
dis_check = 'F';
}while(m_check == 'F' || n_check == 'F' || dis_check == 'F');
我试过只输入 m = 3、n = 3、dis = 2,然后循环重新开始并要求我输入行数。如果我被要求按 f 或其他东西,它就会开始疯狂地循环打印 printf 语句 :)
scanf
returns 它转换的字段数。您有格式字符串 %d%c
;它有:
%d
- 第一个字段%c
- 第二个字段
所以scanf
returns 2.
如果用户输入数字,例如123
并按 Enter,您的 num
将等于 123
,而 term
将等于 \n
。
如果用户输入的数字末尾有乱码,例如123garbage
并按 Enter,您的 num
将等于 123
,term
将等于 g
,并且arbage\n
将保留在输入缓冲区中。
在这两种情况下,scanf
读取一个 int
和一个 char
,所以它 returns 2.
另一个例子:用户输入 garbage123
。在这种情况下,scanf
将无法读取整数,而 return 0.
因此您的代码会检查两种不同形式的错误输出。
scanf("%d%c", &num, &term) != 2
这会检查 scanf
的 return
值。它将正确匹配 return
个参数。因此,如果输入 integer
和字符,它们将存储在变量 num
和 term
和 scanf
returns
2
中。
scanf
将不会 return
2
,在这种情况下,failure
将显示为输出。
输入一个整数将匹配格式化程序 %d
,并将值赋给变量 num
。 %c
格式化程序将采用换行符 ('\n') 并将其存储在变量 term
中。 scanf
returns 2 导致正确分配的 2 个元素(num
和 term
)
如果您不输入整数,格式化程序 %d
将无法正确匹配,scanf
也不会 return 2,产生失败
编辑:您的 do-while 循环变得疯狂,因为您在上次 scanf 中的条件是错误的 (dis != 1 || dis !=2
)。应该是
if(scanf("%d%c", &dis, &dis_check) !=2 || dis_check != '\n' || (dis != 1 && dis !=2))
糟糕 - 现在看到 OP 想知道为什么接近失败并且不一定在寻找操作方法。将其作为参考,因为它确实断言了基本问题:scanf()
。不要将其用于 user 输入。
如果代码确实需要 "get some user input, and wants to make sure that they enter integers",则使用 fgets()
获取行并 然后 处理输入。
将用户输入与 scanning/parse 混合使用总是会导致某些用户输入无法通过检查、stdin
中的额外用户输入或不正确地等待更多输入。
// true implies success
bool Read_int(int *value) {
char buffer[100];
if (fgets(buffer, sizeof buffer, stdin) == NULL) return false; // EOF or error
// Now parse the input
char *endptr;
errno = 0;
long number = strtol(buffer, &endptr, 10);
if (errno) return false; // long overflow
if (number < INT_MIN || number > INT_MAX) return false; // int overflow
if (endptr == buffer) return false; // No conversion
while (isspace((unsigned char) *endptr)) endptr++;
if (*endptr) return false; // non-white-space after number
*value = (int) number;
return true;
}