当字符和整数混合时控制 C 中的用户输入
Control user input in C when there is chars and ints mixed
所以我正在尝试为只接受选项 1,2 和 3 的程序制作一个简单的菜单,我想控制用户输入以防止错误,例如当用户输入 char 而不是 int 时。
现在它控制一些情况,比如如果选项小于 1 或大于 3,如果选项是一个字符它也不会影响但是当用户输入类似“02”或“2a”的东西时它运行选项 2 但应该使该选项无效。
此外,如果我遗漏了更多案例,我想了解它们以及如何克服它们。
#include <stdio.h>
#include <stdlib.h>
void empty_stdin(void);
int main() {
int option;
int rtn;
do {
printf("\n--\nOptions:\n1.Option 1\n2.Option 2\n3.Option 3\n--\n\nPlease chose option (1/2/3) to continue: ");
rtn = scanf("%d", &option);
if (rtn == 0 || option < 1 || option > 3) {
printf("-Invalid Option-\n");
empty_stdin();
} else {
empty_stdin();
switch (option) {
case 1:
printf("Option 1");
break;
case 2:
printf("Option 2");
break;
case 3:
printf("Option 3");
exit(0);
default:
printf("\n-Invalid Option-\n");
}
}
} while (option != 3);
return 0;
}
void empty_stdin(void) {
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
示例Input/Output
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 1
Option 1
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 12
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: char
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 2a
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02a
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
预计Input/Output
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 1
Option 1
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 12
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: char
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 2a
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02a
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
考虑使用 fgets
捕获输入并使用 strtol
解析整数。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
int fgetsint ( int *value, int min, int max, FILE *fin) {
char line[100] = "";
char extra = '[=10=]';
char *end = NULL;
long int number = 0;
if ( fgets ( line, sizeof line, fin)) {//read a line
errno = 0;
number = strtol ( line, &end, 10);
if ( end == line) {// nothing was parsed. no digits
printf ( "input [%s] MUST be a number\n", line);
return 0;// return failure
}
if ( ( errno == ERANGE && ( number == LONG_MAX || number == LONG_MIN))
|| ( errno != 0 && number == 0)) {// parsing error from strtol
perror ( "input error");
return 0;
}
if ( 1 == sscanf ( end, " %c", &extra)) {//parse trailing character
printf ( "enter one number only. try again\n");
return 0;
}
if ( number > max || number < min) {
printf ( "Input [%ld] out of range: min: %d max: %d\n", number, min, max);
return 0;
}
if ( 1 != (int)( end - line)) {
printf ( "input one digit\n");
return 0;// return failure
}
*value = number;//assign number to pointer
}
else {
fprintf ( stderr, "problem fgets\n");
exit ( EXIT_FAILURE);
}
return 1;//success
}
int main ( void) {
int option = 0;
do {
printf("\n--\nOptions:\n1.Option 1\n2.Option 2\n3.Option 3\n--\n\nPlease chose option (1/2/3) to continue: ");
option = 0;
fgetsint ( &option, 1, 3, stdin);
switch (option) {
case 1:
printf("Option 1");
break;
case 2:
printf("Option 2");
break;
case 3:
printf("Option 3");
exit(0);
default:
printf("\n-Invalid Option-\n");
}
} while ( option != 3);
return 0;
}
建议代码如下:
- 干净地编译
- 执行所需的功能
- 处理了所有 'oops' 个案例
- 尊重右边距,用于打印等
现在,建议的代码:
#include <stdio.h>
void empty_stdin( void );
int main( void )
{
int option = 9;
do
{
printf("\n--\nOptions:\n"
"1.Option 1\n"
"2.Option 2\n"
"3.Option 3\n"
"--\n\n"
"Please chose option (1/2/3) to continue: ");
option = getchar();
empty_stdin();
switch (option)
{
case 1:
printf( "Option 1\n" );
break;
case 2:
printf( "Option 2\n" );
break;
case 3:
printf( "Option 3, exiting\n" );
//exit(0);
break;
default:
printf( "\n-option: %d invalid-\n", option );
break;
}
} while ( option != 3 && option != EOF );
return 0;
}
void empty_stdin( void )
{
//int c = getchar();
//while (c != '\n' && c != EOF)
//c = getchar();
int c;
while( (c = getchar() ) != EOF && c != '\n' );
}
所以我正在尝试为只接受选项 1,2 和 3 的程序制作一个简单的菜单,我想控制用户输入以防止错误,例如当用户输入 char 而不是 int 时。
现在它控制一些情况,比如如果选项小于 1 或大于 3,如果选项是一个字符它也不会影响但是当用户输入类似“02”或“2a”的东西时它运行选项 2 但应该使该选项无效。
此外,如果我遗漏了更多案例,我想了解它们以及如何克服它们。
#include <stdio.h>
#include <stdlib.h>
void empty_stdin(void);
int main() {
int option;
int rtn;
do {
printf("\n--\nOptions:\n1.Option 1\n2.Option 2\n3.Option 3\n--\n\nPlease chose option (1/2/3) to continue: ");
rtn = scanf("%d", &option);
if (rtn == 0 || option < 1 || option > 3) {
printf("-Invalid Option-\n");
empty_stdin();
} else {
empty_stdin();
switch (option) {
case 1:
printf("Option 1");
break;
case 2:
printf("Option 2");
break;
case 3:
printf("Option 3");
exit(0);
default:
printf("\n-Invalid Option-\n");
}
}
} while (option != 3);
return 0;
}
void empty_stdin(void) {
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
示例Input/Output
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 1
Option 1
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 12
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: char
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 2a
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02a
Option 2
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
预计Input/Output
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 1
Option 1
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 12
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: char
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 2a
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
Please chose option (1/2/3) to continue: 02a
-Invalid Option-
--
Options:
1.Option 1
2.Option 2
3.Option 3
--
考虑使用 fgets
捕获输入并使用 strtol
解析整数。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
int fgetsint ( int *value, int min, int max, FILE *fin) {
char line[100] = "";
char extra = '[=10=]';
char *end = NULL;
long int number = 0;
if ( fgets ( line, sizeof line, fin)) {//read a line
errno = 0;
number = strtol ( line, &end, 10);
if ( end == line) {// nothing was parsed. no digits
printf ( "input [%s] MUST be a number\n", line);
return 0;// return failure
}
if ( ( errno == ERANGE && ( number == LONG_MAX || number == LONG_MIN))
|| ( errno != 0 && number == 0)) {// parsing error from strtol
perror ( "input error");
return 0;
}
if ( 1 == sscanf ( end, " %c", &extra)) {//parse trailing character
printf ( "enter one number only. try again\n");
return 0;
}
if ( number > max || number < min) {
printf ( "Input [%ld] out of range: min: %d max: %d\n", number, min, max);
return 0;
}
if ( 1 != (int)( end - line)) {
printf ( "input one digit\n");
return 0;// return failure
}
*value = number;//assign number to pointer
}
else {
fprintf ( stderr, "problem fgets\n");
exit ( EXIT_FAILURE);
}
return 1;//success
}
int main ( void) {
int option = 0;
do {
printf("\n--\nOptions:\n1.Option 1\n2.Option 2\n3.Option 3\n--\n\nPlease chose option (1/2/3) to continue: ");
option = 0;
fgetsint ( &option, 1, 3, stdin);
switch (option) {
case 1:
printf("Option 1");
break;
case 2:
printf("Option 2");
break;
case 3:
printf("Option 3");
exit(0);
default:
printf("\n-Invalid Option-\n");
}
} while ( option != 3);
return 0;
}
建议代码如下:
- 干净地编译
- 执行所需的功能
- 处理了所有 'oops' 个案例
- 尊重右边距,用于打印等
现在,建议的代码:
#include <stdio.h>
void empty_stdin( void );
int main( void )
{
int option = 9;
do
{
printf("\n--\nOptions:\n"
"1.Option 1\n"
"2.Option 2\n"
"3.Option 3\n"
"--\n\n"
"Please chose option (1/2/3) to continue: ");
option = getchar();
empty_stdin();
switch (option)
{
case 1:
printf( "Option 1\n" );
break;
case 2:
printf( "Option 2\n" );
break;
case 3:
printf( "Option 3, exiting\n" );
//exit(0);
break;
default:
printf( "\n-option: %d invalid-\n", option );
break;
}
} while ( option != 3 && option != EOF );
return 0;
}
void empty_stdin( void )
{
//int c = getchar();
//while (c != '\n' && c != EOF)
//c = getchar();
int c;
while( (c = getchar() ) != EOF && c != '\n' );
}