【问题标题】:Re-prompting a user until he/she enters a positive integer value greater than 1重新提示用户,直到他/她输入大于 1 的正整数值
【发布时间】:2016-10-19 17:48:29
【问题描述】:

我正在解决 CS50(问题 1),即 water.c。它要求用户编写一个程序,以分钟为单位提示用户他或她的淋浴时长(作为正整数),然后打印等效数量的瓶装水(作为整数)。 淋浴 1 分钟 = 消耗 12 瓶 主要问题:问题是我们必须确保用户输入的分钟数是正数,否则它会不断重新提示他返回 input/scanf 语句。只要他输入他输入长度

>

 #include <stdio.h>
 int main()
 {   int length=0;
    int min=12;
    int bottle=0;
    printf("Enter length of his or her shower in minutes");
    scanf("%d", &length);
    while (length <= 0){
    printf("Enter length of his or her shower in minutes");
    scanf("%d", &length);
    }
    bottle= (min*length);
    printf("%d", bottle);

    return 0;
 }

【问题讨论】:

  • 向我们展示您到目前为止所做的事情,不要只是要求我们为您编写代码
  • 已编辑,现在你可以看到我的代码了 :)
  • 看看strtol。您可以将输入读取为字符串,使用strtol将字符串转换为整数,如果转换过程中有任何错误strtol将通过设置errno来指示:linux.die.net/man/3/strtol
  • 可能重复:stackoverflow.com/questions/28911745/… 试试看。
  • This answer 可能会有所帮助。

标签: c validation input cs50


【解决方案1】:

你可以通过先读取一个字符串,然后提取任意数字来解决这个问题:

#include <stdio.h>

int main(void)
{
    int length = 0;
    char input[100];
    while(length <= 0) {
        printf("Enter length: ");
        fflush(stdout);
        if(fgets(input, sizeof input, stdin) != NULL) {
            if(sscanf(input, "%d", &length) != 1) {
                length = 0;
            }
        }
    }

    printf("length = %d\n", length);
    return 0;
}

节目环节:

Enter length: 0
Enter length: -1
Enter length: abd3
Enter length: 4
length = 4

至关重要的是,我总是检查来自scanf的返回值,成功转换的项目数。

【讨论】:

  • 我不想刻薄:D,但是为什么int main(int argc, char const *argv[]) 如果程序不使用这些参数?只是问问。在我看来应该是int main(void)
  • @Michi 哦好的,这只是我的标准测试文件,已编辑。
  • 虽然可以使用scanf() 完成,但这种方法通常问题少得多,而且可能更简单。
【解决方案2】:

如果您不关心1f 之类的输入,那么上面的答案对您来说是可以的,但是如果您不想接受这种输入,那么以下方法会这样做:

#include<stdio.h>

int checkInput(void);
int main(void){
    int number = checkInput();

    printf("\nYour number is\t%d\n",number);

    return 0;
}

int checkInput(void){
    int option,check;
    char c;

    do{
        printf("Please type a number:\t");

        if(scanf("%d%c",&option,&c) == 0 || c != '\n'){
            while((check = getchar()) != 0 && check != '\n' && check != EOF);
            printf("\tI sayed a Number please\n\n");
        }else{
            if ( option < 1){
                printf("Wrong input!\n");
            }else{
                break;
            }
        }
    }while(1);

    return option;
}

输出:

Please type a number:   1f
    I sayed a Number please

Please type a number:   f1
    I sayed a Number please

Please type a number:   -1
    Wrong input!
Please type a number:   1

Your number is  1

【讨论】:

  • @WeatherVane 你说得对:D。但我的答案并不专注于此。我已经说过这是关于1ff1 之类的输入。而且我也讨厌将我的答案作为教程:d。
  • (check = getchar()) != 0 很好奇。为什么要检查0
  • @chux 与 (check = getchar()) != '\0'(check = getchar()) != 1)2, 3,4....100...n 相同。我只是用了一张额外的支票。
  • 我看到代码做了额外的检查,但是为什么如果遇到空字符就停止读取?看起来适得其反。
  • 这个答案拒绝了42*之类的输入,而我的解决方案没有。
【解决方案3】:

您不需要循环外的第一个提示,因为您已经将长度初始化为零,因此循环将至少提示一次。

在除 Wndows 之外的大多数平台上,您需要刷新标准输出以显示不以换行符结尾的文本。

scanf 将返回只要换行符被缓冲并且单独的%d 不会消耗换行符,因此您需要确保刷新任何剩余字符(包括换行符)以防止无限循环。

最好检查来自scanf() 的返回值,因为它不能保证即使转换失败也不修改其参数。

不清楚为什么min 在这里是一个变量,因为它已初始化但从未重新分配,但大概在最终程序中可​​能是这种情况?

#include <stdio.h>

int main( void )
{   
    int length = 0 ;
    int min = 12 ;
    int bottle = 0 ;

    while( length <= 0 )
    {
        int converted = 0 ;

        printf( "Enter length of his or her shower in minutes: " ) ;
        fflush( stdout ) ;
        converted = scanf( "%d", &length ) ;
        if( converted != 1 )
        {
            length = 0 ;
        }

        while( (c = getchar()) != '\n' && c != EOF ) { } // flush line buffer
    }

    bottle = min * length ;
    printf( "%d", bottle ) ;

    return 0;
}

【讨论】:

  • main 签名至少应为int main(void){}int main(int argc, char* argv[]){}
  • OP 已经在上面解释了回答问题If you enter any char it runs infinite times.。您的回答似乎无法解决此问题。更多的 OP 需要像 This 这样的东西
  • while( getchar() != '\n' ) { } --> EOF 上的无限循环。虽然我怀疑 OP 会关闭stdin
  • @Michi :我只是复制了 OPs 框架——C11 清楚地表明了这一点,C89 允许其他实现定义的签名,我敢打赌任何编译器都会接受这一点。当然在 C++ 中也是有效的。
  • @Michi :您当然是对的-因为无论标准的版本如何,您建议的签名都是有效的,因此应该首选它以获得最大的可移植性。我对向 OP 添加代码持谨慎态度不是解决方案的明确部分,因为它可能会分散注意力。但我们已经分心了。
【解决方案4】:
int min = 0;
do {
   printf("Enter minutes: ");
   scanf("%i", &min);
} while(min <= 0);
//programs resumes after this.

【讨论】:

  • 如果您输入任何字符,它将无限次运行。我只想要正整数值,否则重新提示!
  • SO 不是教程网站,您应该解释一些内容以使其成为答案而不是教程。
  • @HamzaAzam Probabli This is what you need。检查以下hereHereHere。应该回答你所有的问题。
  • @Michi :评论不适用于发布答案,并且场外答案对 SO 社区几乎没有帮助。它不会出现在搜索中,也不能被投票或评论。
  • scanf("%i", min); ==>> scanf("%i", &amp;min);
猜你喜欢
  • 1970-01-01
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
  • 2021-07-07
  • 1970-01-01
相关资源
最近更新 更多