Программа не ожидает ввода текста - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть эта функция, которая читает текст от пользователя и подсчитывает количество букв каждого типа.Однако функция не ожидает ввода данных пользователем при вызове.

Обычно я пытаюсь поставить пробел перед% c, однако добавление этого пробела делает его таким, чтобы программа не продолжала работу послевы нажали ввод.

 void ReadText(int histo[], int *max) {

    int i;
     char userInput;

    printf("ENTER A LINE OF TEXT:\n");
    do{

    if (scanf("%c", &userInput) != 1)
    break;

  if(userInput >= 97 && userInput <= 122)
     histo[userInput-97] = histo[userInput-97] + 1;
  else if(userInput >= 65 && userInput <= 90)
     histo[userInput-65] = histo[userInput-65] + 1;

  }while(userInput != '\n');

  for(i = 0; i < 26; i++)
  printf("%d ", histo[i]);

    *max = histo[0];

   for(i = 0; i < 25; i++)
      if(histo[i] > *max)
         *max = histo[i];
}





int main() {   

   char command;
   int i, max;
   int histo[26] = {0};

   //User Input Validation

   do{

   printf("Enter command (C, R, P, or Q): ");
   scanf(" %c", &command);

   switch(command) {

  case 'C': case 'c':
     for(i = 0; i < 25; i++)
        histo[i] = 0;
     break;            

  case 'R': case 'r':    
     ReadText(histo, &max);
     break;

  case 'P': case 'p':      
     DrawHist(histo, max);
     break;

  case 'Q': case 'q':
     return 0;

  default:

     printf("Invalid Command %c", command);
     printf("\n");      
  }
   }while(1);

   return 0;
}

Ответы [ 3 ]

1 голос
/ 16 апреля 2019

Проблема в вашей основной функции - вы вызываете scanf(" %c", чтобы прочитать команду, которая после этой строки оставляет новую строку во входном буфере. Поэтому, когда вы вызываете ReadText, первое, что он читает, это та новая строка, и она сразу возвращается.

Вам необходимо добавить некоторый код для чтения (и удаления) остальной части текущей строки ввода перед вызовом ReadText.

1 голос
/ 16 апреля 2019

Когда я впервые написал этот ответ, программа main() не была предоставлена. Теперь, когда это предусмотрено, основная проблема заключается в том, что scanf() оставляет новую строку во входном буфере . Когда основная программа читает r (или R), новая строка после нее остается в буфере. Код в ReadText() немедленно читает этот символ новой строки, и ничего более.

Добавление пробела в " %c" в ReadText() означает, что все пробелы, табуляции и новые строки будут прочитаны при обработке пробела, и только когда будет введено что-то, что не является пробелом, ввод прекращается. Для вашего кода использование только "%c" является правильным и необходимым (если вы не решите использовать вместо него getchar()). Вы должны также обращаться с EOF; в ReadText() вы должны проверить:

if (scanf("%c", &userInput) != 1)
    break;

Лучшее исправление, вероятно, заключается в использовании такой функции, как:

static void gobble(void)
{
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        ;
}

и вызовите его через main() после scanf(), чтобы прочитать символ команды:

printf («Введите команду (C, R, P или Q):»); if (scanf ("% c", & command)! = 1) вернуть 0; // EOF наиболее вероятно проглатывают (); * +1027 *

Здесь " %c"main()) разумно. Это не подходит в ReadText().

Помните: scanf(), вероятно, самая сложная функция, которую можно действительно хорошо использовать в стандартном C - она ​​мучительно сложна и неуловима, и на любой конкретный вызов часто влияют предыдущие операции ввода, особенно предыдущие вызовы scanf(). Восстановление после ошибки на входе также довольно сложно, если вы не используете такую ​​функцию, как gobble(), чтобы удалить остатки непрочитанного остатка на линии - но диагностика того, что пошло не так, тоже трудна. Часто лучше прочитать строку с помощью fgets() (или POSIX getline()), а затем отсканировать ее с помощью sscanf(), что позволяет (а) делать несколько попыток анализа одних и тех же данных, а (б) позволяет сообщать о всей неисправной строке, а не о том, какие фрагменты остались после того, как scanf() прочитал некоторые, но не всю строку.

0 голосов
/ 16 апреля 2019

В основном добавлено работает как шарм, спасибо за говорящих людей!

  case 'R': case 'r':   
     while((c = getchar()) != '\n' && c != EOF); //Clear the newlines
     ReadText(histo, &max);
     break;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...