【问题标题】:why is the printf statement executed more than once? [duplicate]为什么 printf 语句执行了多次? [复制]
【发布时间】:2014-06-24 06:03:08
【问题描述】:

计算输入中 +ve、-ve 和零的数量的程序。for 循环中的 printf 语句执行了多次。如何更正此代码。计数正确但输出不是预期的格式.

#include<stdio.h>
main()
{
    int n,pc,nc,zc;
    char s;
    pc=nc=zc=0;
    for(;1;) {
        printf("do you wanna enter: y/n\n");
        s=getchar();
        if(s=='y') {
            printf("enter num:\n");
            scanf("%d",&n);
            if(n>0) {
                pc+=1;
            }
            if(n<0) {
                nc+=1;
            }
            if(n==0) zc+=1;
        }
        if(s=='n') break;
    }
    printf("No.of +ve num: %d \n",pc);  
    printf("No.of -ve num: %d \n",nc);
    printf("No.of zeroes: %d \n",zc);
}

输出:

xplorer@kali:~/Desktop/docs/yk/chap3$ ./a.out
do you wanna enter: y/n
y 
enter num:
4
do you wanna enter: y/n
do you wanna enter: y/n
y
enter num:
8 
do you wanna enter: y/n
do you wanna enter: y/n
y
enter num:
-7     
do you wanna enter: y/n
do you wanna enter: y/n
n
No.of +ve num: 2 
No.of -ve num: 1 
No.of zeroes: 0

【问题讨论】:

  • 你的缩进在源文件中是这样的吗?!
  • 我对缩进并不特别,请赐教。
  • 坦率地说,您的代码绝对令人震惊。这是不可能理解的。你的变量名很差,结构很差,缩进不一致,一切都不一致。

标签: c linux loops


【解决方案1】:

\n 被先前的getchar 调用留在输入缓冲区中,因为它一次读取一个字符。由于 '\n' 也是一个字符,因此 n 下一次迭代 getchar 会读取剩下的 \n 。
您需要刷新输入缓冲区:

int c;
while((c = getchar()) != '\n' && c != EOF);

【讨论】:

    【解决方案2】:
    ...
    {
    printf("enter num:\n");
    scanf("%d",&n);
    ...
    

    上面问题代码的sn-p中的'scanf'从stdin读取一个整数,但只有在用户按下return之后。返回字符 '\n' 也被发送到标准输入,但是,上面的 'scanf' 满足于仅读取整数值,并将 '\n' 字符留在标准输入流中。下次任何函数尝试从标准输入读取时,'\n' 字符将在那里读取。这会导致此处的问题代码出现不良结果:

    ...
    {
    printf("do you wanna enter: y/n\n");
    s=getchar();
    ....
    

    “getchar”函数从标准输入中读取“\n”字符,程序对其进行操作。

    避免此问题的一种方法是让“scanf”函数从缓冲区中读取剩余的“\n”字符。这可以通过改变这个来完成:

    scanf("%d",&n);
    

    到这里:

    scanf("%d%*c",&n);
    

    后者从标准输入流中读取整数值,然后读取(并丢弃)剩余的 '\n' 字符。

    【讨论】:

      【解决方案3】:

      每次从标准输入读取后,从缓冲区中删除所有额外的字符:

      /* discard (flush) remaining chars in stdin */
      while (ch !='\n') ch = getchar();
      

      正如其他答案中所讨论的,在您使用scanf 或其他输入实用程序进行测试后,输入缓冲区中会保留额外的字符。您不能使用任何标准函数(例如 fflush)可靠地刷新输入缓冲区,因为它们适用于 输出 缓冲区而不是输入缓冲区。扫描换行符的简单 while 循环可确保读取所有字符,无论换行符之前是否存在回车,因此可在大多数操作系统之间移植。

      【讨论】:

        【解决方案4】:

        如果您的系统上有curses.h,您可以使用flushinp 函数刷新输入。 检查 C 常见问题:http://c-faq.com/stdio/stdinflush2.html

        【讨论】:

          【解决方案5】:

          您只检查了两个条件,即“y”或“n”,而没有检查另一个,因此它可能会从先前的输入中获取除“y”或“n”以外的输入并继续循环。因此,如果它正在接受任何其他输入并相应地进行更改,只需通过打印来检查。

          【讨论】:

            【解决方案6】:

            替换 s=getchar();与

            do
            {
               s=getchar();
            }while (isspace(s));
            

            一切都会开始的。

            【讨论】:

              猜你喜欢
              • 2017-09-05
              • 1970-01-01
              • 2012-07-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-11-06
              • 2013-05-30
              相关资源
              最近更新 更多