如何正确提示用户输入,直到他们给出有效响应
How to correctly prompt a user for input until they give a valid response
我想打印一条提示信息到标准输出,然后读取
用户输入的标准输入值(例如,数字)。
如果用户输入了无效值,我想再次打印提示,并且
再次阅读他们的回复,直到他们输入有效值(有点像
shells 工作)。
问题是当用户输入无效值时,提示莫名其妙
打印了两次,这不是我想要的。
这是我到目前为止尝试过的,但没有成功:
#include <stdio.h>
const char *prompt = "(Enter 1 to continue)> ";
int get_resp1(void)
{
int r;
fputs(prompt, stdout);
r = getchar() - '0';
if (r != 1)
r = get_resp1();
return r;
}
int get_resp2(void)
{
int r;
r = getchar() - '0';
if (r != 1) {
fputs(prompt, stdout);
r = get_resp2();
}
return r;
}
int get_resp3(void)
{
int r;
fputs(prompt, stdout);
do {
r = getchar() - '0';
if (r != 0)
fputs(prompt, stdout);
} while (r != 1);
return r;
}
int main(void)
{
int response;
/* First attempt: */
/* response = get_resp1(); */
/* Second attempt */
/* fputs(prompt, stdout); */
/* response = get_resp2(); */
/* Third attempt: */
/* response = get_resp3(); */
return response != 1;
}
这是我想要的结果:
(Enter 1 to continue)> 2
(Enter 1 to continue)>
(Enter 1 to continue)> 1
在第一行,我们输入非1的东西,在第二行
行,我们输入一个空行,最后,我们输入 1.
但这是我得到的结果(使用所有三种方法):
(Enter 1 to continue)> 2
(Enter 1 to continue)> (Enter 1 to continue)>
(Enter 1 to continue)> 1
注意提示在第二行打印了两次。
这可以使用 fgets
来实现:
int get_resp4(void)
{
int r;
char buf[0x7f];
char *ptr = buf;
fputs(prompt, stdout);
fgets(buf, sizeof buf, stdin);
while (*ptr && *ptr != '\n' && !isdigit(*ptr))
++ptr;
if (!isdigit(*ptr))
r = get_resp4();
else
r = *ptr - '0';
if (r != 1)
r = get_resp4();
return r;
}
正如所说,如果输入包含值 1
(具有零个或多个空格或制表符),那么它将被接受。任何其他字符组合都将被丢弃。
您可以更改代码以更改行为。这只是尝试使用问题中的 OP 预期的类似处理来演示 OP。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#define MAXBUFFSIZE 100
bool getConfirmation(){
printf("\n%s",">> ");
char buff[MAXBUFFSIZE];
unsigned int success = 0;
while( 1 ){
success = 0;
if( fgets(buff,MAXBUFFSIZE,stdin) == NULL){
fprintf(stderr, "%s\n", "Error in input");
break;
}
for( size_t i = 0; i < strlen(buff); i++){
if(isspace(buff[i]))
continue;
else if( isalpha(buff[i]))
break;
else if( isdigit(buff[i]) ){
if( buff[i] == '1'){
success++;
if( success > 1)
break;
}
else{
success = 0;
break;
}
}
}
if( success == 1 )
break;
success = 0;
printf("\n%s",">> ");
}
if( success == 0)
return false;
return true;
}
int main(){
if( getConfirmation() == true )
printf("%s\n","Continued ... ");
else
printf("%s\n","Error in input");
return 0;
}
我想打印一条提示信息到标准输出,然后读取 用户输入的标准输入值(例如,数字)。
如果用户输入了无效值,我想再次打印提示,并且 再次阅读他们的回复,直到他们输入有效值(有点像 shells 工作)。
问题是当用户输入无效值时,提示莫名其妙 打印了两次,这不是我想要的。
这是我到目前为止尝试过的,但没有成功:
#include <stdio.h>
const char *prompt = "(Enter 1 to continue)> ";
int get_resp1(void)
{
int r;
fputs(prompt, stdout);
r = getchar() - '0';
if (r != 1)
r = get_resp1();
return r;
}
int get_resp2(void)
{
int r;
r = getchar() - '0';
if (r != 1) {
fputs(prompt, stdout);
r = get_resp2();
}
return r;
}
int get_resp3(void)
{
int r;
fputs(prompt, stdout);
do {
r = getchar() - '0';
if (r != 0)
fputs(prompt, stdout);
} while (r != 1);
return r;
}
int main(void)
{
int response;
/* First attempt: */
/* response = get_resp1(); */
/* Second attempt */
/* fputs(prompt, stdout); */
/* response = get_resp2(); */
/* Third attempt: */
/* response = get_resp3(); */
return response != 1;
}
这是我想要的结果:
(Enter 1 to continue)> 2
(Enter 1 to continue)>
(Enter 1 to continue)> 1
在第一行,我们输入非1的东西,在第二行 行,我们输入一个空行,最后,我们输入 1.
但这是我得到的结果(使用所有三种方法):
(Enter 1 to continue)> 2
(Enter 1 to continue)> (Enter 1 to continue)>
(Enter 1 to continue)> 1
注意提示在第二行打印了两次。
这可以使用 fgets
来实现:
int get_resp4(void)
{
int r;
char buf[0x7f];
char *ptr = buf;
fputs(prompt, stdout);
fgets(buf, sizeof buf, stdin);
while (*ptr && *ptr != '\n' && !isdigit(*ptr))
++ptr;
if (!isdigit(*ptr))
r = get_resp4();
else
r = *ptr - '0';
if (r != 1)
r = get_resp4();
return r;
}
正如所说,如果输入包含值 1
(具有零个或多个空格或制表符),那么它将被接受。任何其他字符组合都将被丢弃。
您可以更改代码以更改行为。这只是尝试使用问题中的 OP 预期的类似处理来演示 OP。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#define MAXBUFFSIZE 100
bool getConfirmation(){
printf("\n%s",">> ");
char buff[MAXBUFFSIZE];
unsigned int success = 0;
while( 1 ){
success = 0;
if( fgets(buff,MAXBUFFSIZE,stdin) == NULL){
fprintf(stderr, "%s\n", "Error in input");
break;
}
for( size_t i = 0; i < strlen(buff); i++){
if(isspace(buff[i]))
continue;
else if( isalpha(buff[i]))
break;
else if( isdigit(buff[i]) ){
if( buff[i] == '1'){
success++;
if( success > 1)
break;
}
else{
success = 0;
break;
}
}
}
if( success == 1 )
break;
success = 0;
printf("\n%s",">> ");
}
if( success == 0)
return false;
return true;
}
int main(){
if( getConfirmation() == true )
printf("%s\n","Continued ... ");
else
printf("%s\n","Error in input");
return 0;
}