使用 %d 跳过字符输入的 scanf
Skipping scanf for character input with %d
int valid = 0;
while (!valid) {
printf("\nEnter number of characters (1-30)> ");
scanf("%d", & n);
printf("\nInclude numbers (Y/N)> ");
scanf(" %c", & nf);
printf("\nInclude symbols (Y/N)> ");
scanf(" %c", & sf);
//cond1 and cond2 initialized here
if (cond1 && cond2)
valid = 1;
else
printf("Invalid input");
}
我需要为第一个整数扫描实现错误输入检测功能。如果用户输入的是字符而不是整数,则跳过第二个 scanf,直接进入第三个 scanf。如果在 %d 上输入字符,我该如何阻止这种情况发生?如果用户输入的是字符而不是数字,我想再次请求输入
只需检查 scanf()
的 return 值,在您的情况下:
if ((scanf("%d", &n) != 1) /* should return 1 if 1 int is read */
{
fprintf(stderr,"Input not a number\n");
exit(EXIT_FAILURE) /* include stdlib or just use return */
}
请注意,在大数的情况下,scanf()
不会针对 算术溢出 提供任何保护。您可能想使用 fgets()
并稍后使用 strtol()
等函数解析该字符串以确保安全。
示例:https://godbolt.org/z/oaMhac983
如果您想再次要求输入,我建议您改用 fgets()
,然后检查该字符串是否为非数字字符。
您可以使用 strspn()
,它 return 是第一个参数中出现在第二个参数中的字符数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_N 13 /* save space [=11=] and \n */
int main(void) {
int num = 0;
char n[MAX_N] = {0};
char *numbers = "-+0123456789";
while (1) {
if (fgets(n, MAX_N, stdin) == NULL) /* check return value of fgets() */
{
exit(EXIT_FAILURE);
}
if (strspn(n, numbers) ==
strlen(n) - 1) /* only numbers were read (exclude '\n')*/
{
if (sscanf(n, "%d", &num) != 1) /* check return value of scanf() */
{
exit(EXIT_FAILURE);
}
break;
}
}
printf("%d\n", num);
return 0;
}
你的意思好像是下面这样
#include <stdio.h>
int main(void)
{
int n;
const int MIN = 1, MAX = 30;
do
{
printf( "\nEnter number of characters (%d-%d)> ", MIN, MAX );
if ( scanf( "%d", &n ) != 1 )
{
clearerr( stdin );
scanf( "%*[^\n]" );
scanf( "%*c" );
n = 0;
}
} while ( n < MIN || MAX < n );
printf( "n = %d\n", n );
return 0;
}
程序输出可能看起来像
Enter number of characters (1-30)> Hello
Enter number of characters (1-30)> 0
Enter number of characters (1-30)> 31
Enter number of characters (1-30)> Bye
Enter number of characters (1-30)> 10
n = 10
或类似
#include <stdio.h>
int main(void)
{
int n = 0;
const int MIN = 1, MAX = 30;
printf( "\nEnter number of characters (%d-%d)> ", MIN, MAX );
if ( scanf( "%d", &n ) != 1 )
{
clearerr( stdin );
scanf( "%*[^\n]" );
scanf( "%*c" );
n = 0;
}
char nf, sf;
if ( n != 0 )
{
printf("\nInclude numbers (Y/N)> ");
scanf( " %c", &nf );
}
else
{
printf("\nInclude symbols (Y/N)> ");
scanf(" %c", &sf);
}
return 0;
}
How can I stop this from happening in case of a character input on %d?
检查 scanf()
的 return 值。
scanf("%d", &n);
returns 不同条件下的 3 个值中的第 1 个:
1 扫描成功。在 n
.
中扫描了 int
值
0 由于非数字输入(OP 感兴趣的情况),扫描失败。 n
中的值未更改。
由于没有更多输入(文件结束),EOF 扫描失败。 n
中的值未更改。
由于输入错误导致 EOF 扫描失败(罕见)。 n
中的值不确定。
do {
printf("\nEnter number of characters (1-30)> ");
int retval = scanf("%d", &n);
if (retval == EOF) {
printf("End of file or input error. Quitting\n");
exit(-1);
}
if (retval == 0) {
// read in rest of line (except \n) and toss it.
scanf("%*[^\n]");
continue;
}
// If here, valid `int` input read, now testfor range.
} while (n < 1 || n > 30);
....
考虑编写 以编写提示并阅读 int
。
int valid = 0;
while (!valid) {
printf("\nEnter number of characters (1-30)> ");
scanf("%d", & n);
printf("\nInclude numbers (Y/N)> ");
scanf(" %c", & nf);
printf("\nInclude symbols (Y/N)> ");
scanf(" %c", & sf);
//cond1 and cond2 initialized here
if (cond1 && cond2)
valid = 1;
else
printf("Invalid input");
}
我需要为第一个整数扫描实现错误输入检测功能。如果用户输入的是字符而不是整数,则跳过第二个 scanf,直接进入第三个 scanf。如果在 %d 上输入字符,我该如何阻止这种情况发生?如果用户输入的是字符而不是数字,我想再次请求输入
只需检查 scanf()
的 return 值,在您的情况下:
if ((scanf("%d", &n) != 1) /* should return 1 if 1 int is read */
{
fprintf(stderr,"Input not a number\n");
exit(EXIT_FAILURE) /* include stdlib or just use return */
}
请注意,在大数的情况下,scanf()
不会针对 算术溢出 提供任何保护。您可能想使用 fgets()
并稍后使用 strtol()
等函数解析该字符串以确保安全。
示例:https://godbolt.org/z/oaMhac983
如果您想再次要求输入,我建议您改用 fgets()
,然后检查该字符串是否为非数字字符。
您可以使用 strspn()
,它 return 是第一个参数中出现在第二个参数中的字符数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_N 13 /* save space [=11=] and \n */
int main(void) {
int num = 0;
char n[MAX_N] = {0};
char *numbers = "-+0123456789";
while (1) {
if (fgets(n, MAX_N, stdin) == NULL) /* check return value of fgets() */
{
exit(EXIT_FAILURE);
}
if (strspn(n, numbers) ==
strlen(n) - 1) /* only numbers were read (exclude '\n')*/
{
if (sscanf(n, "%d", &num) != 1) /* check return value of scanf() */
{
exit(EXIT_FAILURE);
}
break;
}
}
printf("%d\n", num);
return 0;
}
你的意思好像是下面这样
#include <stdio.h>
int main(void)
{
int n;
const int MIN = 1, MAX = 30;
do
{
printf( "\nEnter number of characters (%d-%d)> ", MIN, MAX );
if ( scanf( "%d", &n ) != 1 )
{
clearerr( stdin );
scanf( "%*[^\n]" );
scanf( "%*c" );
n = 0;
}
} while ( n < MIN || MAX < n );
printf( "n = %d\n", n );
return 0;
}
程序输出可能看起来像
Enter number of characters (1-30)> Hello
Enter number of characters (1-30)> 0
Enter number of characters (1-30)> 31
Enter number of characters (1-30)> Bye
Enter number of characters (1-30)> 10
n = 10
或类似
#include <stdio.h>
int main(void)
{
int n = 0;
const int MIN = 1, MAX = 30;
printf( "\nEnter number of characters (%d-%d)> ", MIN, MAX );
if ( scanf( "%d", &n ) != 1 )
{
clearerr( stdin );
scanf( "%*[^\n]" );
scanf( "%*c" );
n = 0;
}
char nf, sf;
if ( n != 0 )
{
printf("\nInclude numbers (Y/N)> ");
scanf( " %c", &nf );
}
else
{
printf("\nInclude symbols (Y/N)> ");
scanf(" %c", &sf);
}
return 0;
}
How can I stop this from happening in case of a character input on %d?
检查 scanf()
的 return 值。
scanf("%d", &n);
returns 不同条件下的 3 个值中的第 1 个:
1 扫描成功。在 n
.
中扫描了 int
值
0 由于非数字输入(OP 感兴趣的情况),扫描失败。 n
中的值未更改。
由于没有更多输入(文件结束),EOF 扫描失败。 n
中的值未更改。
由于输入错误导致 EOF 扫描失败(罕见)。 n
中的值不确定。
do {
printf("\nEnter number of characters (1-30)> ");
int retval = scanf("%d", &n);
if (retval == EOF) {
printf("End of file or input error. Quitting\n");
exit(-1);
}
if (retval == 0) {
// read in rest of line (except \n) and toss it.
scanf("%*[^\n]");
continue;
}
// If here, valid `int` input read, now testfor range.
} while (n < 1 || n > 30);
....
考虑编写 int
。