Справка по коду C (не могу найти причину, которая вызывает проблему) - PullRequest
2 голосов
/ 05 июня 2011

Привет, чтобы сократить его, ниже код

Код

// 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) :. Затем возникает проблема, вместо того, чтобы ждать, пока я наберу y или n, программа просто завершится сама, что означает, что в командной строке Windows она выдаст мне строку Press any key to continue.....

Я продолжаю читать код построчно, чтобы найти любую семантическую ошибку (предположим, что нет синтаксисаошибка, так как компилятор жаловался бы, если таковая имеется) или любая логическая ошибка, которую я сделал, но безрезультатно. Так что я подозреваю, что есть какие-то правила C, в которых упоминается, что мы не должны предлагать использовать if() с символом в качестве тестового значениякогда он заключен в цикл while() или в какую-либо другую вещь, которой я пренебрегал ??

Спасибо, что связали себя, чтобы прочитать мою проблему, надеюсь, я действительно научусь у вас, ребята, укажите на любыеошибкаЯ сделал, как ученик, который готов принять любой комментарий или учение, которое является правильным.

Ответы [ 5 ]

4 голосов
/ 05 июня 2011

Вы используете scanf(). Мое общее правило: не надо.

Проблема состоит в том, что scanf() практически любого другого символа оставит символы после прочитанного вами значения (обычно новой строки) в буфере, за исключением того, что %c читает следующий символ независимо от того, что это такое. Таким образом, вы получаете там новую строку, а затем ответ y / n передается на next scanf().

Я предпочитаю читать строки, а затем sscanf() из них; таким образом я точно знаю, что я получаю.

3 голосов
/ 05 июня 2011

Поставьте getchar () после каждого scanf, чтобы очистить входной буфер stdin от символа перевода строки в конце \ n, который добавляется в буфер, когда пользователь нажимает enter.

0 голосов
/ 05 июня 2011

Вы вводите номер и затем нажимаете клавишу ввода. Строка формата "%d" будет читать до первого целого числа и не будет читать введенный вами символ новой строки. Этот символ перевода строки остается в буфере, который читается в первом scanf в цикле со спецификатором "%c". Поэтому check == 'y' становится ложным, поскольку check содержит 0x0a, то есть эквивалент ASCII новой строки, после того, как он прочитал новую строку.

Обратите внимание, что если вы хотите, чтобы ваш фрагмент кода работал именно так, вам нужно вводить числа и параметры y / n один за другим, без новой строки (0x0a), пробела (0x20) или других сепараторы. Например, если вы хотите суммировать список 1, 2, 3, 4, 5, вам необходимо ввести его в код следующим образом: 1y2y3y4y5n. Если вы введете оператор printf, печатающий значение status после scanf с запросом да / нет, вы можете ясно увидеть, что последний непрочитанный символ читается "%c".

Если вы хотите ввести цифры и разделенные опции, вам нужно использовать дополнительный символ. Что вы можете сделать, используя getchar () или используя оператор подавления аргумента в строке формата: scanf ("%*c%c", &check). Этот "%*c" будет читать один символ из stdin, а затем просто отбрасывать его, а затем "%c" получит ваш ввод в переменную check. Но если вы введете дополнительную новую строку или, скажем, будете иметь некоторые пробелы перед опциями, которые вы вводите, или после введенного вами числа, то это приведет к тому, что только один из них будет использован вышеуказанным и отброшен, и та же проблема возникнет.

Вы также можете использовать строку scanf (" %c", &check);. " %c" (обратите внимание на конечный пробел) пропускает любое количество пробелов, которые вы вводите перед вводом первого символа.

На самом деле это зависит от того, как вы хотите интерпретировать и обрабатывать ввод, вам нужно настроить его в соответствии с ним. Вероятно, сделайте:

 char check[2];

 while (status == 1)
 {
    sum += num;

    printf("Do you wanna add more integer?(y/n) :");   //Asking for user next action
    scanf("%s" , check);

    if ((check[0] == 'y')&&(check[1] == '\0'))    //Check user's answer  
       status = scanf("%d" , &num);
    else
       status = 0;
 }

или просто используйте strcmp (check, "y") == 0 или другие способы.

0 голосов
/ 05 июня 2011

статус начинается как неопределенный. Вы хотите убедиться, что цикл ввода / суммирования запускается хотя бы один раз, поэтому вы должны сначала установить его в 1. Таким образом, вы знаете, что он всегда будет запущен в первый раз.

То, что @geekosaur сказал о scanf (), верно: оно оставит вещи во входном буфере, что вызовет странное поведение для следующих операторов ввода. Но хорошо использовать scanf (), если вы очищаете stdin каждый раз, когда используете его. Если вы используете Windows, есть готовая функция:

fflush(stdin);

Если вы используете другую операционную систему (или хотите, чтобы ваш код был переносимым), вы можете выполнить поиск аналогичной функции для включения в вашу программу. Ввод в C - это всего лишь одна из тех ужасных вещей, с которыми должен обходиться начинающий программист (к этому вы привыкли). Я полагаю, что это также может помочь, если вы будете ставить пробелы в начале строки формата scanf () каждый раз, когда вы ее используете - например.

scanf(" %d");

Это должно указывать программе игнорировать любые пробелы, уже находящиеся во входных данных (включая символы новой строки).

Стоит отметить, что у вас действительно есть 2 входа статуса - int status и проверка символов. Вы можете немного упростить для себя задачу, установив условие в качестве пользовательского ввода:

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 ().

0 голосов
/ 05 июня 2011

Вот отредактированный код, работающий на меня:

#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;
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...