C无穷多while循环
这是一个简单的类程序,它提示用户以分钟为单位输入淋浴时间(作为正整数,根据需要重新提示),然后打印同等数量的瓶装水(作为整数) 它假设淋浴每分钟使用1.5加仑(192盎司)的水和一个16盎司大小的塑料瓶 我的do-while循环成功地拒绝了负数和0,但是,如果在提示以分钟为单位输入淋浴长度时输入诸如“foo”之类的文本,程序将进入无限循环,永远运行循环并打印“您的淋浴有多长(以分钟为单位)”:“ 有没有办法改进while条件以避免这种情况C无穷多while循环,c,loops,scanf,do-while,infinite,C,Loops,Scanf,Do While,Infinite,这是一个简单的类程序,它提示用户以分钟为单位输入淋浴时间(作为正整数,根据需要重新提示),然后打印同等数量的瓶装水(作为整数) 它假设淋浴每分钟使用1.5加仑(192盎司)的水和一个16盎司大小的塑料瓶 我的do-while循环成功地拒绝了负数和0,但是,如果在提示以分钟为单位输入淋浴长度时输入诸如“foo”之类的文本,程序将进入无限循环,永远运行循环并打印“您的淋浴有多长(以分钟为单位)”:“ 有没有办法改进while条件以避免这种情况 #include <stdio.h> in
#include <stdio.h>
int min_to_bottles(int *n);
int main(void)
{
int minutes;
int bottles;
do
{
printf("How long is your shower(in minutes)?:");
scanf("%i", &minutes);
}
while (minutes < 1);
bottles = min_to_bottles(&minutes);
printf("Equivalent of bottles used per shower is: %i\n", bottles);
}
int min_to_bottles(int *n)
{
int bottles;
int oz = 192 * *n;
bottles = oz/16;
return bottles;
}
#包括
int min_至_瓶(int*n);
内部主(空)
{
整数分钟;
int瓶;
做
{
printf(“您的淋浴时间(分钟)?:”;
scanf(“%i”、&minutes);
}
而(分钟<1);
瓶子=最小到最小瓶子(&分钟);
printf(“每次淋浴使用的瓶子的当量为:%i\n”,瓶子);
}
int min_至_瓶(int*n)
{
int瓶;
int oz=192**n;
瓶子=盎司/16;
返回瓶子;
}
始终检查scanf()的返回值。
:
将
minutes
初始化为0
将避免在scanf()
失败的情况下(例如通过输入文本)使用未定义的值计算瓶子。始终检查scanf()
的返回值:
将minutes
初始化为0
将避免在scanf()
失败(例如输入文本)的情况下使用未定义的值计算瓶子。当您输入文本时,它与%i
格式说明符不匹配,因此,文本被卡在输入缓冲区中,它一直试图读取相同的内容
如果没有找到匹配项,则需要刷新缓冲区。通过检查scanf
的返回值,您将知道该情况是否正确,该值返回成功匹配的模式数
int minutes = 0;
while (minutes < 1)
{
printf("How long is your shower(in minutes)?:");
int count = scanf("%i", &minutes);
if (count < 1) {
scanf("%*s"); // The * tells scanf to read the input but not assign it to anything
}
}
int分钟=0;
而(分钟<1)
{
printf(“您的淋浴时间(分钟)?:”;
int count=scanf(“%i”&分钟);
如果(计数<1){
scanf(“%*s”);//命令scanf读取输入,但不将其分配给任何对象
}
}
当您输入文本时,它与%i
格式说明符不匹配,因此文本会卡在输入缓冲区中,并一直尝试读取相同的内容
如果没有找到匹配项,则需要刷新缓冲区。通过检查scanf
的返回值,您将知道该情况是否正确,该值返回成功匹配的模式数
int minutes = 0;
while (minutes < 1)
{
printf("How long is your shower(in minutes)?:");
int count = scanf("%i", &minutes);
if (count < 1) {
scanf("%*s"); // The * tells scanf to read the input but not assign it to anything
}
}
int分钟=0;
而(分钟<1)
{
printf(“您的淋浴时间(分钟)?:”;
int count=scanf(“%i”&分钟);
如果(计数<1){
scanf(“%*s”);//命令scanf读取输入,但不将其分配给任何对象
}
}
不要使用scanf(“%i”,…)
主要问题是,未转换为数字的错误输入会保留在stdin
中,直到另一个函数读取它。由于代码没有检查scanf()
的返回值,minutes
的值未知为良好值,do。。。而(分钟<1)代码>可以很容易地重复循环
解决方案:读取一行输入,转换为数字,有效数字:
要处理意外的用户输入,请从读取一行输入开始
char buf[80];
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOF();
然后解析缓冲区中的数字
errno = 0;
char *endptr;
long num == strtol(buf, &endptr, 0);
// detect overflow and no conversiosn
if (errno || buf == endptr) Handle_BadInput();
// Ignore trailing white-space
while (isspace((unsigned char) *endptr) endptr++;
if (*endptr) Handle_BadInput();
#define SHOWER_TIME_MIN (1 /* minute */)
#define SHOWER_TIME_MAX (60 /* minute */)
if (num < SHOWER_TIME_MIN || num > SHOWER_TIME_MAX) Handle_BadInput();
验证数字
errno = 0;
char *endptr;
long num == strtol(buf, &endptr, 0);
// detect overflow and no conversiosn
if (errno || buf == endptr) Handle_BadInput();
// Ignore trailing white-space
while (isspace((unsigned char) *endptr) endptr++;
if (*endptr) Handle_BadInput();
#define SHOWER_TIME_MIN (1 /* minute */)
#define SHOWER_TIME_MAX (60 /* minute */)
if (num < SHOWER_TIME_MIN || num > SHOWER_TIME_MAX) Handle_BadInput();
#定义淋浴时间(1/*分钟*/)
#定义淋浴时间最大值(60/*分钟*/)
如果(numSHOWER_TIME_MAX)Handle_baddinput();
将所有这些放在一个helper函数中
示例不要使用scanf(“%i”,…)
主要问题是,未转换为数字的错误输入会保留在stdin
中,直到另一个函数读取它。由于代码没有检查scanf()
的返回值,minutes
的值未知为良好值,do。。。而(分钟<1)代码>可以很容易地重复循环
解决方案:读取一行输入,转换为数字,有效数字:
要处理意外的用户输入,请从读取一行输入开始
char buf[80];
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOF();
然后解析缓冲区中的数字
errno = 0;
char *endptr;
long num == strtol(buf, &endptr, 0);
// detect overflow and no conversiosn
if (errno || buf == endptr) Handle_BadInput();
// Ignore trailing white-space
while (isspace((unsigned char) *endptr) endptr++;
if (*endptr) Handle_BadInput();
#define SHOWER_TIME_MIN (1 /* minute */)
#define SHOWER_TIME_MAX (60 /* minute */)
if (num < SHOWER_TIME_MIN || num > SHOWER_TIME_MAX) Handle_BadInput();
验证数字
errno = 0;
char *endptr;
long num == strtol(buf, &endptr, 0);
// detect overflow and no conversiosn
if (errno || buf == endptr) Handle_BadInput();
// Ignore trailing white-space
while (isspace((unsigned char) *endptr) endptr++;
if (*endptr) Handle_BadInput();
#define SHOWER_TIME_MIN (1 /* minute */)
#define SHOWER_TIME_MAX (60 /* minute */)
if (num < SHOWER_TIME_MIN || num > SHOWER_TIME_MAX) Handle_BadInput();
#定义淋浴时间(1/*分钟*/)
#定义淋浴时间最大值(60/*分钟*/)
如果(numSHOWER_TIME_MAX)Handle_baddinput();
将所有这些放在一个helper函数中
示例while((scanf(“%d”,&minutes)==1)和&(minutes<1))代码>!scanf()
有一个返回值,请使用它。这不会解决问题,您仍然可能有分钟错误,因此最初将其设置为-1
,并在while
循环后检查以确保其正确。@iharob但是为什么在第一次输入错误后scanf没有阻塞?您如何知道它是无限的?while((scanf(%d“,&minutes)==1)和(&(minutes<1))代码>!scanf()
有一个返回值,请使用它。这不会解决问题,您仍然可能有分钟错误,因此最初将其设置为-1
,并在while
循环后检查以确保其正确。@iharob但是为什么在第一次输入错误后scanf不阻塞?您如何知道它是无限的?谢谢。我仍然是C语言的初学者,我很感激能帮助我更好地理解编程的所有低级方面的任何答案。@TomasVrba-很高兴能提供帮助。请不要犹豫,尽情享受你的C旅程吧!非常感谢。我仍然是C语言的初学者,我很感激能帮助我更好地理解编程的所有低级方面的任何答案。@TomasVrba-很高兴能提供帮助。请不要犹豫,尽情享受你的C旅程吧!