C代码帮助(找不到导致问题的原因)

时间:2011-06-04 20:49:27

标签: c

问候,简而言之,下面是代码

守则

// This program would sum up all the integer provided by user

#include <stdio.h>

int main(void)
{
 int sum = 0;                  // initialize and declare variable
 int num;
 char check;
 int status;

 printf("Please enter an integer to be summed :"); // prompt user for an integer
 status = scanf("%d" , &num);                                

  while(status == 1)                              //If user enter an integer , while loop test condition is true
  {
    sum = sum + num;                           //sum the input integer
    printf("Do you wanna add more integer?(y/n) :");   //Asking for user next action
    scanf("%c" , &check);

          if(check == 'y')                   //Check user's answer

        status = scanf("%d" , &num);

    else

        status = 0;

  }


 return 0;
}

问题

我运行程序时要做的第一件事是提供一个整数,之后它会打印出控制字符串Do you wanna add more integer?(y/n) :。然后问题引起,而不是等我输入{{ 1}}或y,程序将自行结束,这意味着在Windows命令提示符下它会给我n行。

我一直逐行阅读代码以找到任何语义错误(假设没有语法错误,因为编译器会抱怨,如果有的话)或者我做的任何逻辑错误,但是没有用。所以我怀疑是它有C的任何规则提到我们不应该在Press any key to continue....循环或我忽略的任何其他东西中包含字符作为测试值时使用if()吗?

感谢你保持自己的阅读我的问题,希望我真的向你们学习,指出我做的任何错误,因为我是一个学习者,准备接受任何评论或教学是正确的。

5 个答案:

答案 0 :(得分:4)

您正在使用scanf()。我的一般规则是:不要。

问题是scanf()几乎任何东西都会在缓冲区中读取的值(通常是换行符)之后留下字符,除了%c读取下一个字符而不管它是什么。所以你在那里获得了换行符,然后y / n响应被传递给 next scanf()

我更喜欢阅读行,然后sscanf()。这样我就知道我到底得到了什么。

答案 1 :(得分:3)

在每个scanf之后放置getchar()以从用户按下回车时添加到缓冲区的尾随换行符'\ n'中清除stdin输入缓冲区。

答案 2 :(得分:0)

您正在输入一个数字,然后按Enter键。 "%d"格式字符串将读取第一个整数,而不读取您输入的换行符。该换行符将保留在缓冲区内,该缓冲区将使用scanf说明符在循环中的第一个"%c"上读取。因此check == 'y'变为false,因为check包含0x0a,即读取新行后的等效换行符。

请注意,如果您想准确地编写代码段,那么您需要一个接一个地输入数字和y / n选项,而不需要任何换行符(0x0a)或空格({{1} })或其他分隔符。例如,如果您想要汇总列表1,2,3,4,5,则需要在代码中输入以下内容:0x20。如果您在1y2y3y4y5n询问是/否之后输入printf语句打印status值,则可以清楚地看到{{1}正在读取上一个未读字符}。

如果你想输入数字和选项分开你需要的是消耗额外的字符。您可以使用scanf或使用格式字符串中的参数抑制运算符来执行此操作:"%c"。此getchar ()会从scanf ("%*c%c", &check)中读取一个字符然后将其丢弃,然后"%*c"会将您的输入输入stdin变量。但是如果你输入一个额外的新行,或者在你输入的选项之前,或者在你输入的数字之后有一些尾随空格,那么它只会使其中一个被上面消耗并丢弃,同样的问题会出现。

您也可以使用字符串"%c" check(注意尾随空格)将跳过您在输入第一个字符之前输入的任意数量的空白字符。

这实际上取决于您想要解释和处理输入的方式,您需要根据它进行调整。可能会:

scanf (" %c", &check);

或仅使用" %c"或其他方式。

答案 3 :(得分:-1)

以下是为我工作的编辑代码:

#include <stdio.h>
#include <conio.h>
int main(void)
{

   int sum = 0;                  
   int num;
   char check;
   int status=1;

   printf("Please enter an integer to be summed :");
   status = scanf("%d" , &num);      
   while(status == 1)
   {
      sum = sum + num;                          
      printf("Do you wanna add more integer?(y/n) :");   
      fflush(stdin);
      check = getche();

      if(check == 'y')                   

         status = scanf("%d" , &num);
      else

         status = 0;
   }
    printf("\nThe sum is: %d",sum);
    getch();
    return 0;
 }

答案 4 :(得分:-1)

状态从未定义开始。您希望确保输入/求和循环至少运行一次,因此您应该首先将其设置为1。这样你知道它将永远是第一次运行。

@geekosaur所说的关于scanf()的内容是正确的 - 它会将内容留在输入缓冲区中,这将导致后续输入语句的奇怪行为。但是使用scanf()是很好的,只要你每次使用它都清除stdin。如果您使用的是Windows,则有一个现成的功能:

fflush(stdin);

如果您正在使用其他操作系统(或者您希望代码可移植),则可以搜索要包含在程序中的类似功能。 C中的输入只是初学者程序员需要解决的可怕事情之一(你已经习惯了)。我相信如果你每次使用它时在scanf()格式字符串的开头放置空格也可能会有所帮助 - 例如。

scanf(" %d");

这应该告诉程序忽略输入中已有的任何空格(包括换行符)。

有一点需要注意的是,这里确实有2个状态输入 - int状态和char检查。您可以通过将条件设置为用户输入来使事情变得更简单:

char check = 'y';

...

while(check == 'y')

这应该创建与现在相同的行为。我改为使用do-while循环:

// This program would sum up all the integer provided by user

#include <stdio.h>

int main(void)
{
    int sum = 0;
    int num;
    char check;

    do // a do-while loop always runs at least once - perfect for input validation
    {
        printf("Please enter an integer to be summed :");
        fflush(stdin); //only in Windows - remove for other OS
        scanf(" %d" , &num);
        sum += num; //another way of writing sum = sum + num                                
        printf("Do you wanna add more integer?(y/n) :");
        fflush(stdin); //only in Windows - remove for other OS
        scanf(" %c" , &check);    
    }while(check == 'y');

    //if you want to print the sum...
    printf("The sum is %i\n", sum);
    getchar();

    return 0;
}

在Windows上,删除了fflush()调用后,它确实对我有用。