C:scanf()和while()(来自C Primer Plus的编程练习7.10)
我还在读斯蒂芬·普拉塔的C初级读物。下面的代码是我试图解决第七章的第十个编程练习。 我的问题是:当输入一个字符而不是一个整数时,为什么程序会无限循环?如何防止这种行为C:scanf()和while()(来自C Primer Plus的编程练习7.10),c,while-loop,scanf,C,While Loop,Scanf,我还在读斯蒂芬·普拉塔的C初级读物。下面的代码是我试图解决第七章的第十个编程练习。 我的问题是:当输入一个字符而不是一个整数时,为什么程序会无限循环?如何防止这种行为 #include <stdio.h> // taxrates #define TAXRATE_1 .15 #define TAXRATE_2 .28 // category limits #define SINGLE_LIMIT 17850 #define HEAD_OF_HOUSEHOLD_LI
#include <stdio.h>
// taxrates
#define TAXRATE_1 .15
#define TAXRATE_2 .28
// category limits
#define SINGLE_LIMIT 17850
#define HEAD_OF_HOUSEHOLD_LIMIT 23900
#define MARRIED_JOINT_LIMIT 29750
#define MARRIED_SEPARAT_LIMIT 14875
// bases
#define SINGLE_BASE SINGLE_LIMIT * TAXRATE_1
#define HEAD_OF_HOUSEHOLD_BASE HEAD_OF_HOUSEHOLD_LIMIT * TAXRATE_1
#define MARRIED_JOINT_BASE MARRIED_JOINT_LIMIT * TAXRATE_1
#define MARRIED_SEPARAT_BASE MARRIED_SEPARAT_LIMIT * TAXRATE_1
int main(void)
{
int selection;
float income, tax;
while (1)
{
printf("*******************************************************\n"
"Please enter the number of your category:\n"
"1) Single\n2) Head of Household\n3) Married, Joint\n4) Married, Separat\n5) quit\n"
"*******************************************************\n");
scanf("%d", &selection);
if (selection >= 1 && selection <= 4)
{
printf("Enter income: ");
scanf("%f", &income);
switch (selection)
{
case 1:
if (income < SINGLE_LIMIT)
tax = income * TAXRATE_1;
else
tax = SINGLE_BASE + (income - SINGLE_LIMIT) * TAXRATE_2;
printf("Single income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 2:
if (income < HEAD_OF_HOUSEHOLD_LIMIT)
tax = income * TAXRATE_1;
else
tax = HEAD_OF_HOUSEHOLD_BASE+ (income - HEAD_OF_HOUSEHOLD_LIMIT) * TAXRATE_2;
printf("Head of Household income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 3:
if (income < MARRIED_JOINT_LIMIT)
tax = income * TAXRATE_1;
else
tax = MARRIED_JOINT_BASE + (income - MARRIED_JOINT_LIMIT) * TAXRATE_2;
printf("Married joint income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 4:
if (income < MARRIED_SEPARAT_LIMIT)
tax = income * TAXRATE_1;
else
tax = MARRIED_SEPARAT_BASE + (income - MARRIED_SEPARAT_LIMIT) * TAXRATE_2;
printf("Married separat income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
}
}
else if (selection == 5)
{
printf("Done.");
break;
}
else
printf("Please enter a number between 1 and 5.\n");
}
return 0;
}
仅当else部分中的选择值为5时,程序中的While循环才会退出。
但是,每当您输入一个字符时,选择的值不能是5,因此它永远不会从循环中出来,并使程序循环无限运行 仅当else部分中的选择值为5时,程序中的While循环才会退出。 但是,每当您输入一个字符时,选择的值不能是5,因此它永远不会从循环中出来,并使程序循环无限运行 我的问题是:当一个角色被激活时,为什么程序会无限循环 输入而不是整数,如何防止这种行为
#include <stdio.h>
// taxrates
#define TAXRATE_1 .15
#define TAXRATE_2 .28
// category limits
#define SINGLE_LIMIT 17850
#define HEAD_OF_HOUSEHOLD_LIMIT 23900
#define MARRIED_JOINT_LIMIT 29750
#define MARRIED_SEPARAT_LIMIT 14875
// bases
#define SINGLE_BASE SINGLE_LIMIT * TAXRATE_1
#define HEAD_OF_HOUSEHOLD_BASE HEAD_OF_HOUSEHOLD_LIMIT * TAXRATE_1
#define MARRIED_JOINT_BASE MARRIED_JOINT_LIMIT * TAXRATE_1
#define MARRIED_SEPARAT_BASE MARRIED_SEPARAT_LIMIT * TAXRATE_1
int main(void)
{
int selection;
float income, tax;
while (1)
{
printf("*******************************************************\n"
"Please enter the number of your category:\n"
"1) Single\n2) Head of Household\n3) Married, Joint\n4) Married, Separat\n5) quit\n"
"*******************************************************\n");
scanf("%d", &selection);
if (selection >= 1 && selection <= 4)
{
printf("Enter income: ");
scanf("%f", &income);
switch (selection)
{
case 1:
if (income < SINGLE_LIMIT)
tax = income * TAXRATE_1;
else
tax = SINGLE_BASE + (income - SINGLE_LIMIT) * TAXRATE_2;
printf("Single income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 2:
if (income < HEAD_OF_HOUSEHOLD_LIMIT)
tax = income * TAXRATE_1;
else
tax = HEAD_OF_HOUSEHOLD_BASE+ (income - HEAD_OF_HOUSEHOLD_LIMIT) * TAXRATE_2;
printf("Head of Household income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 3:
if (income < MARRIED_JOINT_LIMIT)
tax = income * TAXRATE_1;
else
tax = MARRIED_JOINT_BASE + (income - MARRIED_JOINT_LIMIT) * TAXRATE_2;
printf("Married joint income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 4:
if (income < MARRIED_SEPARAT_LIMIT)
tax = income * TAXRATE_1;
else
tax = MARRIED_SEPARAT_BASE + (income - MARRIED_SEPARAT_LIMIT) * TAXRATE_2;
printf("Married separat income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
}
}
else if (selection == 5)
{
printf("Done.");
break;
}
else
printf("Please enter a number between 1 and 5.\n");
}
return 0;
}
当您输入的内容不是scanf所期望的,而是您传递给scanf的格式字符串所定义的内容时,它将忽略该内容并返回。但该无效输入不会从输入流中清除。因此,当读忽略循环再次在程序中继续时,循环将永远继续
因此,为了解决这个问题:
尽可能避免扫描。使用fgets并使用sscanf处理输入,这提供了更好的错误控制。
检查返回值scanf以确定扫描是否成功。
通常的清除方法是在遇到无效输入时读取输入流中的所有字符:
else {
int c;
printf("Please enter a number between 1 and 5.\n");
while((c = getchar()) != '\n' && c != EOF) ; /* reads and discards */
}
我的问题是:当一个角色被激活时,为什么程序会无限循环
输入而不是整数,如何防止这种行为
#include <stdio.h>
// taxrates
#define TAXRATE_1 .15
#define TAXRATE_2 .28
// category limits
#define SINGLE_LIMIT 17850
#define HEAD_OF_HOUSEHOLD_LIMIT 23900
#define MARRIED_JOINT_LIMIT 29750
#define MARRIED_SEPARAT_LIMIT 14875
// bases
#define SINGLE_BASE SINGLE_LIMIT * TAXRATE_1
#define HEAD_OF_HOUSEHOLD_BASE HEAD_OF_HOUSEHOLD_LIMIT * TAXRATE_1
#define MARRIED_JOINT_BASE MARRIED_JOINT_LIMIT * TAXRATE_1
#define MARRIED_SEPARAT_BASE MARRIED_SEPARAT_LIMIT * TAXRATE_1
int main(void)
{
int selection;
float income, tax;
while (1)
{
printf("*******************************************************\n"
"Please enter the number of your category:\n"
"1) Single\n2) Head of Household\n3) Married, Joint\n4) Married, Separat\n5) quit\n"
"*******************************************************\n");
scanf("%d", &selection);
if (selection >= 1 && selection <= 4)
{
printf("Enter income: ");
scanf("%f", &income);
switch (selection)
{
case 1:
if (income < SINGLE_LIMIT)
tax = income * TAXRATE_1;
else
tax = SINGLE_BASE + (income - SINGLE_LIMIT) * TAXRATE_2;
printf("Single income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 2:
if (income < HEAD_OF_HOUSEHOLD_LIMIT)
tax = income * TAXRATE_1;
else
tax = HEAD_OF_HOUSEHOLD_BASE+ (income - HEAD_OF_HOUSEHOLD_LIMIT) * TAXRATE_2;
printf("Head of Household income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 3:
if (income < MARRIED_JOINT_LIMIT)
tax = income * TAXRATE_1;
else
tax = MARRIED_JOINT_BASE + (income - MARRIED_JOINT_LIMIT) * TAXRATE_2;
printf("Married joint income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
case 4:
if (income < MARRIED_SEPARAT_LIMIT)
tax = income * TAXRATE_1;
else
tax = MARRIED_SEPARAT_BASE + (income - MARRIED_SEPARAT_LIMIT) * TAXRATE_2;
printf("Married separat income of: %.2f$ Tax: %.2f$\n", income, tax);
break;
}
}
else if (selection == 5)
{
printf("Done.");
break;
}
else
printf("Please enter a number between 1 and 5.\n");
}
return 0;
}
当您输入的内容不是scanf所期望的,而是您传递给scanf的格式字符串所定义的内容时,它将忽略该内容并返回。但该无效输入不会从输入流中清除。因此,当读忽略循环再次在程序中继续时,循环将永远继续
因此,为了解决这个问题:
尽可能避免扫描。使用fgets并使用sscanf处理输入,这提供了更好的错误控制。
检查返回值scanf以确定扫描是否成功。
通常的清除方法是在遇到无效输入时读取输入流中的所有字符:
else {
int c;
printf("Please enter a number between 1 and 5.\n");
while((c = getchar()) != '\n' && c != EOF) ; /* reads and discards */
}
您可能必须在计算机上运行代码来检查代码。任何整数值都是有效的,即不会导致无限循环。是的,它可以接受任何整数值,但要退出while循环,变量选择的值应为5。如果您必须仔细阅读该问题,则会在输入字符时询问为什么它没有从循环中出来。希望现在很清楚,我只希望选择值为5时循环停止。为什么输入字符后不能输入任何新数字?在第一次打印后,scanf会发生什么变化?为什么输入字符后程序不停止等待用户输入?您可能必须在计算机上运行代码来检查代码。任何整数值都是有效的,即不会导致无限循环。是的,它可以接受任何整数值,但要退出while循环,变量选择的值应为5。如果您必须仔细阅读该问题,则会在输入字符时询问为什么它没有从循环中出来。希望现在很清楚,我只希望选择值为5时循环停止。为什么输入字符后不能输入任何新数字?在第一次打印后,scanf会发生什么变化?为什么输入字符后程序不停止等待用户输入?不幸的是,其他功能还没有引入。我是否理解正确:来自scanf的未识别输入保留在inputstream中,一旦被getchar识别,将被丢弃,直到“\n”。是的,您理解正确。稍后您可以了解这些函数:只是要记住scanf的缺陷&为什么它不是首选。不幸的是,其他函数还没有被引入。我是否理解正确:来自scanf的未识别输入保留在inputstream中,一旦被getchar识别,将被丢弃,直到“\n”。是的,您理解正确。稍后您可以了解这些功能:只是要记住scanf的缺陷&为什么它不是首选。