Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C无穷多while循环_C_Loops_Scanf_Do While_Infinite - Fatal编程技术网

C无穷多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

这是一个简单的类程序,它提示用户以分钟为单位输入淋浴时间(作为正整数,根据需要重新提示),然后打印同等数量的瓶装水(作为整数)

它假设淋浴每分钟使用1.5加仑(192盎司)的水和一个16盎司大小的塑料瓶

我的do-while循环成功地拒绝了负数和0,但是,如果在提示以分钟为单位输入淋浴长度时输入诸如“foo”之类的文本,程序将进入无限循环,永远运行循环并打印“您的淋浴有多长(以分钟为单位)”:“

有没有办法改进while条件以避免这种情况

#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旅程吧!