【问题标题】:End while loop with ctrl+d, scanf?用 ctrl+d 结束 while 循环,scanf?
【发布时间】:2015-07-30 00:38:05
【问题描述】:

我希望在用户决定以 (Ctrl+d) (即 EOF)结束之前询问用户“他们想写多少圈”?

额外的问题:如果我写一个字母,例如“k”,它会发出垃圾邮件。我该如何改变?

#include <stdio.h>
int main ()
{
    int i;
    int x;

    printf("\nHow many circles do you want to write?\n");
    scanf("%d", &x);

    while(x != EOF)
    {
        for (i = 1; i <= x; i = i + 1)
        {
            putchar('o');
        }
        printf("\nHow many circles do you want to write?"
               "(to end program click ctrl+d at the same time!))\n");
        scanf("%d", &x);
    }
    printf("\n\n Bye! \n\n");
    return 0;
}  

【问题讨论】:

    标签: c while-loop printf scanf eof


    【解决方案1】:

    您的程序最大的问题是scanf 不会将EOF 读入变量。但是,仅仅解决这个问题并不能使您的程序完全正确,因为您的代码中还有其他问题:

    • 您的代码会重复自己 - 如果可能,您应该统一处理第一次迭代和后续迭代的代码。
    • 您的代码不会处理无效输入 - 当最终用户输入非数字数据时,您的程序会进入无限循环。
    • 您的代码遵循 C 的旧风格 - 十五年来不需要在顶部声明所有变量。你应该在循环中声明你的循环变量。

    以下是解决所有这些缺点的方法:

    int x;
    for (;;) {
        printf("\nHow many circles do you want to write? (to end the program click Ctrl+D at the same time!)\n");
        int res = scanf("%d", &x);
        if (res == EOF) break;
        if (res == 1) {
             ... // Draw x circles here
        } else {
            printf("Invalid input is ignored.\n");
            scanf("%*[^\n]");
        }
    }
    printf("\n\n Bye! \n\n");
    return 0;
    

    【讨论】:

    • 所以 x=scanf,如果给它一个 int(只有 int's?)总是返回“x==1”?在 else 语句中,我不确定为什么需要 scanf("%*[^\n]"),它会一直读取到换行?
    • @Estonia_girl scanf 将在您到达文件末尾时返回 EOF,或从零到 N 的数字,其中 N 是不带星号的格式说明符的数量.当 return 不是 EOF 时,scanf 会告诉您它扫描了多少元素。在您的情况下,只有一个%d,因此读取成功时返回值为1,读取失败时返回值为零。scanf("%*[^\n]")%d 无法读取数字时执行。此调用忽略(由于星号)直到'\n' 的所有内容,以清除用户输入的非数字垃圾缓冲区。
    【解决方案2】:

    根据man pagescanf()return EOF,而不是scan EOF 以x 作为值。

    返回值

    这些函数返回成功匹配和分配的输入项的数量,该数量可能少于提供的数量,在早期匹配失败的情况下甚至为零。

    如果在第一次成功转换或匹配失败之前到达输入结尾,则返回值EOF......

    还有,

    如果我写一个字母,例如“k”,它会发出垃圾邮件,我该如何更改?

    如果输入一个char 值,则会导致匹配失败,在您的情况下,scanf() 返回0,而不是1

    因此,您必须收集scanf()返回值,并检查该值是否符合所需条件。您可以将代码更改为

    int retval = 0;
    while ((retval = scanf("%d", &x))!= EOF && (retval == 1))
    

    【讨论】:

      【解决方案3】:

      如果允许#include,则有两个方便的函数 bool kbhit() 和 char getch()。 所以你可以写

      char c=0;
      if(kbhit()) c = getch();
      if(c== whatever code ctrl+d returns) x=EOF;
      

      提示:看看当您输入字母而不是数字时 scanf(%d,&x) 返回的内容。

      【讨论】:

        【解决方案4】:

        您可以逐个字符输入读取字符:

        #include <stdio.h>                                                             
        int main ()                                                                    
        {                                                                              
            int i;                                                                     
            int x = 0;                                                                 
            int nb = 0;                                                                
        
        
            while(x != EOF)                                                            
            {                                                                          
                printf("\nHow many circles do you want to write?\n");                  
                nb = 0;                                                                
                for (x = getchar(); x != '\n'; x = getchar()) {                        
                    if (x == EOF)                                                      
                        goto end;                                                      
                    if (x >= '0' && x <= '9') {                                        
                        nb = nb * 10 + x - '0';                                        
                    }                                                                  
                }                                                                      
                for (i = 0; i < nb; i++)                                               
                {                                                                      
                    putchar('o');                                                      
                }                                                                      
            }                                                                          
        end:                                                                           
            printf("\n\n Bye! \n\n");                                                  
            return 0;                                                                  
        }     
        

        【讨论】:

          猜你喜欢
          • 2022-01-22
          • 2016-07-22
          • 2018-10-09
          • 1970-01-01
          • 1970-01-01
          • 2012-08-10
          • 2012-05-14
          • 1970-01-01
          • 2014-04-20
          相关资源
          最近更新 更多