问候,简而言之,下面是代码
// This program would sum up all the integer provided by user
#include <stdio.h>
int main(void)
{
int sum = 0; // initialize and declare variable
int num;
char check;
int status;
printf("Please enter an integer to be summed :"); // prompt user for an integer
status = scanf("%d" , &num);
while(status == 1) //If user enter an integer , while loop test condition is true
{
sum = sum + num; //sum the input integer
printf("Do you wanna add more integer?(y/n) :"); //Asking for user next action
scanf("%c" , &check);
if(check == 'y') //Check user's answer
status = scanf("%d" , &num);
else
status = 0;
}
return 0;
}
问题
我运行程序时要做的第一件事是提供一个整数,之后它会打印出控制字符串Do you wanna add more integer?(y/n) :
。然后问题引起,而不是等我输入{{ 1}}或y
,程序将自行结束,这意味着在Windows命令提示符下它会给我n
行。
我一直逐行阅读代码以找到任何语义错误(假设没有语法错误,因为编译器会抱怨,如果有的话)或者我做的任何逻辑错误,但是没有用。所以我怀疑是它有C的任何规则提到我们不应该在Press any key to continue....
循环或我忽略的任何其他东西中包含字符作为测试值时使用if()
吗?
感谢你保持自己的阅读我的问题,希望我真的向你们学习,指出我做的任何错误,因为我是一个学习者,准备接受任何评论或教学是正确的。
答案 0 :(得分:4)
您正在使用scanf()
。我的一般规则是:不要。
问题是scanf()
几乎任何东西都会在缓冲区中读取的值(通常是换行符)之后留下字符,除了%c
读取下一个字符而不管它是什么。所以你在那里获得了换行符,然后y / n响应被传递给 next scanf()
。
我更喜欢阅读行,然后sscanf()
。这样我就知道我到底得到了什么。
答案 1 :(得分:3)
在每个scanf之后放置getchar()以从用户按下回车时添加到缓冲区的尾随换行符'\ n'中清除stdin输入缓冲区。
答案 2 :(得分:0)
您正在输入一个数字,然后按Enter键。 "%d"
格式字符串将读取第一个整数,而不读取您输入的换行符。该换行符将保留在缓冲区内,该缓冲区将使用scanf
说明符在循环中的第一个"%c"
上读取。因此check == 'y'
变为false,因为check
包含0x0a
,即读取新行后的等效换行符。
请注意,如果您想准确地编写代码段,那么您需要一个接一个地输入数字和y / n选项,而不需要任何换行符(0x0a
)或空格({{1} })或其他分隔符。例如,如果您想要汇总列表1,2,3,4,5,则需要在代码中输入以下内容:0x20
。如果您在1y2y3y4y5n
询问是/否之后输入printf
语句打印status
值,则可以清楚地看到{{1}正在读取上一个未读字符}。
如果你想输入数字和选项分开你需要的是消耗额外的字符。您可以使用scanf
或使用格式字符串中的参数抑制运算符来执行此操作:"%c"
。此getchar ()
会从scanf ("%*c%c", &check)
中读取一个字符然后将其丢弃,然后"%*c"
会将您的输入输入stdin
变量。但是如果你输入一个额外的新行,或者在你输入的选项之前,或者在你输入的数字之后有一些尾随空格,那么它只会使其中一个被上面消耗并丢弃,同样的问题会出现。
您也可以使用字符串"%c"
check
(注意尾随空格)将跳过您在输入第一个字符之前输入的任意数量的空白字符。
这实际上取决于您想要解释和处理输入的方式,您需要根据它进行调整。可能会:
scanf (" %c", &check);
或仅使用" %c"
或其他方式。
答案 3 :(得分:-1)
以下是为我工作的编辑代码:
#include <stdio.h>
#include <conio.h>
int main(void)
{
int sum = 0;
int num;
char check;
int status=1;
printf("Please enter an integer to be summed :");
status = scanf("%d" , &num);
while(status == 1)
{
sum = sum + num;
printf("Do you wanna add more integer?(y/n) :");
fflush(stdin);
check = getche();
if(check == 'y')
status = scanf("%d" , &num);
else
status = 0;
}
printf("\nThe sum is: %d",sum);
getch();
return 0;
}
答案 4 :(得分:-1)
状态从未定义开始。您希望确保输入/求和循环至少运行一次,因此您应该首先将其设置为1。这样你知道它将永远是第一次运行。
@geekosaur所说的关于scanf()的内容是正确的 - 它会将内容留在输入缓冲区中,这将导致后续输入语句的奇怪行为。但是使用scanf()是很好的,只要你每次使用它都清除stdin。如果您使用的是Windows,则有一个现成的功能:
fflush(stdin);
如果您正在使用其他操作系统(或者您希望代码可移植),则可以搜索要包含在程序中的类似功能。 C中的输入只是初学者程序员需要解决的可怕事情之一(你已经习惯了)。我相信如果你每次使用它时在scanf()格式字符串的开头放置空格也可能会有所帮助 - 例如。
scanf(" %d");
这应该告诉程序忽略输入中已有的任何空格(包括换行符)。
有一点需要注意的是,这里确实有2个状态输入 - int状态和char检查。您可以通过将条件设置为用户输入来使事情变得更简单:
char check = 'y';
...
while(check == 'y')
这应该创建与现在相同的行为。我改为使用do-while循环:
// This program would sum up all the integer provided by user
#include <stdio.h>
int main(void)
{
int sum = 0;
int num;
char check;
do // a do-while loop always runs at least once - perfect for input validation
{
printf("Please enter an integer to be summed :");
fflush(stdin); //only in Windows - remove for other OS
scanf(" %d" , &num);
sum += num; //another way of writing sum = sum + num
printf("Do you wanna add more integer?(y/n) :");
fflush(stdin); //only in Windows - remove for other OS
scanf(" %c" , &check);
}while(check == 'y');
//if you want to print the sum...
printf("The sum is %i\n", sum);
getchar();
return 0;
}
在Windows上,删除了fflush()调用后,它确实对我有用。