而循环卡在无限循环中,我不';我不知道为什么 #包括 #包括 #包括 #包括 int main(int argc,char*argv[]) { printf(“此程序测试您的整数算术技能。\n” “您应该回答以下问题\n” 计算机对整数算术执行的规则,而不是\n “浮点算术。在后面按'Enter'键\n” “您已经输入了您的输入。当您希望完成时\n” 在测试中,输入-9876作为问题的答案。\n “\n”); int n1,n2,answer,user_answer,a,b,int_per; char-op,c; 浮点数,计数,计数,计数; 计数=0; 计数r=0; 计数w=0; printf(“你的问题是什么?”); scanf(“%d%c%d”、&n1、&op、&n2); 做 { 计数++; printf(“什么是%d%c%d?”,n1,op,n2); 如果(op=='+') { 答案=n1+n2; } else if(op='-') { 答案=n1-n2; } else if(op='%')) { 答案=n1%n2; } else if(op=='/')) { 答案=n1/n2; } else if(op=='*') { 答案=n1*n2; } c=scanf(“%d”,用户回答(&U); 如果(用户回答==回答) { printf(“正确!\n\n”); 计数r++; } 否则如果(用户回答==-9876) { 计数=计数-1; 打破 } 如果(c!=1),则为else { printf(“无效输入,它必须只是一个数字\n\n”); printf(“什么是%d%c%d?”,n1,op,n2); } else if(用户回答!=回答) { printf(“错误!\n\n”); 计数w++; } }while(用户回答!=-9876); per=(计数/计数)*100; a=(int)计数; b=(int)计数w; int_per=整数(per); printf(“\n您得到了%d对%d错,分数为%d%c\n”,a, b、 国际单位,37); 返回退出成功; }
上面的代码应该循环询问问题和答案,直到用户输入-9876作为答案,然后程序终止并给出他们的分数。这一切都有效,除了!!一方面当用户在输入中输入非数字时。当这种情况发生时,应该说“输入无效,请再试一次”,然后再问同样的问题。比如说 你的问题是什么9+9 什么是9+9hmmm,8 输入无效,请重试 什么是9+9 所以。。用户输入“hmmm”,而不是用同样的问题再次提示用户,然后正确地扫描,它只是跳入一个无限循环。我想知道如何解决这个问题而循环卡在无限循环中,我不';我不知道为什么 #包括 #包括 #包括 #包括 int main(int argc,char*argv[]) { printf(“此程序测试您的整数算术技能。\n” “您应该回答以下问题\n” 计算机对整数算术执行的规则,而不是\n “浮点算术。在后面按'Enter'键\n” “您已经输入了您的输入。当您希望完成时\n” 在测试中,输入-9876作为问题的答案。\n “\n”); int n1,n2,answer,user_answer,a,b,int_per; char-op,c; 浮点数,计数,计数,计数; 计数=0; 计数r=0; 计数w=0; printf(“你的问题是什么?”); scanf(“%d%c%d”、&n1、&op、&n2); 做 { 计数++; printf(“什么是%d%c%d?”,n1,op,n2); 如果(op=='+') { 答案=n1+n2; } else if(op='-') { 答案=n1-n2; } else if(op='%')) { 答案=n1%n2; } else if(op=='/')) { 答案=n1/n2; } else if(op=='*') { 答案=n1*n2; } c=scanf(“%d”,用户回答(&U); 如果(用户回答==回答) { printf(“正确!\n\n”); 计数r++; } 否则如果(用户回答==-9876) { 计数=计数-1; 打破 } 如果(c!=1),则为else { printf(“无效输入,它必须只是一个数字\n\n”); printf(“什么是%d%c%d?”,n1,op,n2); } else if(用户回答!=回答) { printf(“错误!\n\n”); 计数w++; } }while(用户回答!=-9876); per=(计数/计数)*100; a=(int)计数; b=(int)计数w; int_per=整数(per); printf(“\n您得到了%d对%d错,分数为%d%c\n”,a, b、 国际单位,37); 返回退出成功; },c,while-loop,infinite-loop,C,While Loop,Infinite Loop,上面的代码应该循环询问问题和答案,直到用户输入-9876作为答案,然后程序终止并给出他们的分数。这一切都有效,除了!!一方面当用户在输入中输入非数字时。当这种情况发生时,应该说“输入无效,请再试一次”,然后再问同样的问题。比如说 你的问题是什么9+9 什么是9+9hmmm,8 输入无效,请重试 什么是9+9 所以。。用户输入“hmmm”,而不是用同样的问题再次提示用户,然后正确地扫描,它只是跳入一个无限循环。我想知道如何解决这个问题 谢谢当读取输入时出错时,您应该清除错误状态并跳过该行的其余部分
谢谢当读取输入时出错时,您应该清除错误状态并跳过该行的其余部分,然后再尝试读取更多用户输入 更换管路:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
int main(int argc, char * argv[])
{
printf("This program tests your integer arithmetic skills.\n"
"You should answer the questions following the same \n"
"rules that computers do for integers arithmetic, not \n"
"floating-point arithmetic. Hit the 'Enter' key after \n"
"you have typed in your input. When you wish to finish \n"
"the test, enter -9876 as the answer to a question.\n"
"\n");
int n1, n2, answer, user_answer, a, b, int_per;
char op, c;
float per, count, count_r, count_w;
count = 0;
count_r = 0;
count_w = 0;
printf("What is your question? ");
scanf("%d %c %d", &n1, &op, &n2);
do
{
count++;
printf("What is %d %c %d ? ", n1, op, n2);
if (op == '+')
{
answer = n1 + n2;
}
else if (op == '-')
{
answer = n1 - n2;
}
else if (op == '%')
{
answer = n1 % n2;
}
else if (op == '/')
{
answer = n1 / n2;
}
else if (op == '*')
{
answer = n1 * n2;
}
c = scanf("%d", &user_answer);
if (user_answer == answer)
{
printf("Correct!\n\n");
count_r++;
}
else if (user_answer == -9876)
{
count = count - 1;
break;
}
else if (c != 1)
{
printf("Invalid input, it must be just a number\n\n");
printf("What is %d %c %d ? ", n1, op, n2);
}
else if (user_answer != answer)
{
printf("Wrong!\n\n");
count_w++;
}
} while(user_answer != -9876);
per = (count_r / count) * 100;
a = (int) count_r;
b = (int) count_w;
int_per = roundf(per);
printf("\nYou got %d right and %d wrong, for a score of %d%c\n", a,
b, int_per, 37);
return EXIT_SUCCESS;
}
借
其中skipRestOfLine()
可以实现为:
else if (c != 1)
{
printf("Invalid input, it must be just a number\n\n");
// Clear the error states.
clearerr(stdin);
// Skip the rest of the line
skipRestOfLine(stdin);
printf("What is %d %c %d ? ", n1, op, n2);
}
在通话中
scanf("%d%c%d",&n1, &op, &n2) use this code
%d
转换说明符希望看到十进制数字字符序列;它将告诉scanf
跳过任何前导空格,然后读取十进制数字字符直到第一个非十进制数字字符,然后将结果转换并保存到user\u answer
。如果您键入12aEnter,scanf
将读取并使用'1'
和'2'
字符,将值12
分配给user\u answer
并返回1(对于一个成功的转换和分配),在输入流中保留'a'
和换行字符
键入“hmmm”
时,第一个非空白字符不是十进制数字,因此scanf
保留该字符,不为用户答案分配任何内容,并返回0
。使用“%d”
转换说明符对scanf
的所有剩余调用都将执行相同的操作
因此,您需要确保您的scanf
成功,如果没有成功,请在执行另一次读取之前清除输入流中的所有字符,如下所示:
c = scanf("%d", &user_answer);
if ( (c = scanf( "%d", &user_answer ) ) == 0 )
{
/**
* input matching failure, clear stray characters from input stream
* up to the next newline character
*/
while ( getchar() != '\n' )
; // empty loop
}
else if ( c == EOF )
{
// error occurred during input operation
}
else
{
// do something with user_answer
}
在我的第一个示例中,您会注意到,%d
转换说明符接受了输入“12a”
;它将12
转换并分配给user\u answer
,在输入流中留下'a'
字符,以干扰下一次读取。理想情况下,您希望完全拒绝这种格式错误的输入。您可以执行以下操作:
c = scanf("%d", &user_answer);
if ( (c = scanf( "%d", &user_answer ) ) == 0 )
{
/**
* input matching failure, clear stray characters from input stream
* up to the next newline character
*/
while ( getchar() != '\n' )
; // empty loop
}
else if ( c == EOF )
{
// error occurred during input operation
}
else
{
// do something with user_answer
}
另一个选项是将输入读取为文本,然后使用strtol
库函数将其转换为结果类型:
/**
* Repeatedly prompt and read input until we get a valid decimal string
*/
for( ;; )
{
int c, dummy;
printf("What is %d %c %d ? ", n1, op, n2);
if ( ( c = scanf("%d%c", &user_answer, &dummy ) == 2 )
{
/**
* If the character immediately following our numeric input is
* whitespace, then we have a good input, break out of the read loop
*/
if ( isspace( dummy ) )
break;
else
{
fprintf( stderr, "Non-numeric character follows input, try again...\n" );
while ( getchar() != '\n' )
; // empty loop body
}
}
else if ( c == 1 )
{
/**
* No character following successful decimal input, meaning we
* hit an EOF condition before any trailing characters were seen.
* We'll consider this a good input for our purposes and break
* out of the read loop.
*/
break;
}
else if ( c == 0 )
{
/**
* User typed in one or more non-digit characters; reject the input
* and clear out the input stream
*/
fprintf( stderr, "Non-numeric input\n" );
/**
* Consume characters from the input stream until we see a newline.
*/
while ( ( getchar() != '\n' )
; // empty loop body
}
else
{
/**
* Input error or EOF on read; we'll treat this as a fatal
* error and bail out completely.
*/
fprintf( stderr, "Error occurred during read, panicking...\n" );
exit( 0 );
}
}
那是我喜欢的方法
这些混乱中的任何一个都将取代生产线
for ( ;; )
{
char input[SIZE]; // for some reasonable SIZE value, at least 12 to handle
// a 32-bit int (up to 10 digits plus sign plus
// string terminator
printf("What is %d %c %d ? ", n1, op, n2);
if ( fgets( input, sizeof input, stdin ) )
{
char *check; // will point to first non-digit character in input buffer
int tmp = (int) strtol( input, &check, 10 );
if ( isspace( *check ) || *check == 0 )
{
user_answer = tmp;
break;
}
else
{
fprintf( stderr, "%s is not a valid input, try again\n", input );
}
}
else
{
/**
* error or EOF on input, treat this as a fatal error and bail
*/
fprintf( stderr, "EOF or error while reading input, exiting...\n" );
exit( 0 );
}
}
在阅读了所有你可能会想的内容之后,“C语言中的交互式输入确实是一件让人头疼的事”。你是对的。当输入无效时清除输入缓冲区。当你用scanf(“%d”,&value)
扫描一个整数,而输入不是一个有效的整数时,scanf
返回0,输入返回到它开始的位置,即非数字输入之前。随后的调用将反复尝试重新解析相同的无效输入。您应该scanf(“%*s”)
跳过它。更好的方法是,将整行的fgets
和sscanf
读入其中。我不明白为什么要使用输入-9876
?您在scanf函数中使用了%d%c%d之间的空格..将垃圾值分配到&n1、&op和n2之间variables@NeErAjKuMaR:不,没有;格式字符串中的空格告诉scanf跳过空白字符。为什么fgetc()
而不是getc()
?@JonathanLeffler,我不明白为什么一个比另一个好。getc()
可以是宏fgetc()
保证是一个函数。如果getc()
是一个宏,那是因为它可以执行得更好。有点夸张
c = scanf("%d", &user_answer);