Какой лучший способ прочитать символ? - PullRequest
2 голосов
/ 21 октября 2010

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

int main(int argc, char** argv)
{
 char op;

 do
 {
  printf("¿Sigues?");
  scanf("%c",&op);
 }while(op=='s' || op=='S');
 return 0;
}

Ответы [ 4 ]

2 голосов
/ 22 октября 2010

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

Входной поток пуст, когда scanf() вызывается первый раз в цикле, поэтому он ждет, когда вы что-то наберете.Вы набираете s и нажимаете клавишу Enter, поэтому поток ввода содержит символы s и \n (перевод строки).scanf() удаляет s из входного потока и присваивает его op.Когда scanf() вызывается во второй раз, входной поток не пуст;в нем по-прежнему есть символ \n, поэтому scanf() читает его и присваивает его op, что приводит к сбою условия цикла, поэтому цикл завершается.

Есть несколько способов обойти эту проблему.Я собираюсь порекомендовать прочитать строки в отличие от отдельных символов, использующих fgets(), следующим образом:

char op[3] = {0}; // input character + newline character + 0 terminator

do
{
  printf("¿Sigues?");
  if (fgets(op, sizeof op, stdin))
  {
    /**
     * Check for a newline character in the input.  If it's not there
     * then the user typed in too many characters.  In order to keep
     * the input stream from getting clogged up with bad input, read
     * until we find a newline character.
     */
    char tmp[3];
    char *newline = strchr(op, '\n');
    while (!newline && fgets(tmp, sizeof tmp, stdin))
    {
      newline = strchr(tmp, '\n');
    }
  }
  else
  {
    printf("Error while reading input\n");
    op[0] = 0;
  }
} while (tolower(op[0]) == 's');
1 голос
/ 21 октября 2010

scanf сбрасывается только после чтения новой строки.это не может быть сделано независимым от платформы способом

1 голос
/ 21 октября 2010
op = getc(stdin);
0 голосов
/ 22 октября 2010

Вы видите строку "Sigues" дважды, потому что во входном потоке еще есть \n.Если вы введете символ и нажмете клавишу ввода, в вашем потоке ввода появятся два символа.Ваш scanf форматер определяет только один символ, поэтому scanf читает один символ и затем продвигается.Однако следующий символ в потоке - \n, следовательно, выход из цикла на втором ходу.

NB.Техника @eduffy getc(stdin) будет делать то же самое, в stdin все еще есть \n.Вам нужно как-то продвинуться дальше этого \n.

Как насчет чтения в вашем символе, а затем сжимать оставшуюся часть потока до символа \n?Я попробовал это, и это работает для меня:

char op;

do
 {
  printf("¿Sigues?");
  scanf("%c",&op);
  while(getchar() != '\n') continue;
}while(op=='s'|| op=='S');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...