Как получить пользовательский ввод без использования scanf в консольном приложении? - PullRequest
1 голос
/ 22 февраля 2010

Я пытаюсь разрешить пользователям просто нажимать Enter, ничего не печатая, и использовать это, чтобы означать принятие значения по умолчанию. scanf не выполняет то, что я хочу, и приложение все еще «блокирует»: следующая строка кода не запускается .

Единственный способ - набрать что-то, ТОГДА нажать Enter.

Я пытался использовать NSFileHandle и fileHandleWithStandardInput ; однако, кажется, что пользователь теперь вынужден нажать Ctrl-D, чтобы указать EOF .

Кто-то предложил использовать fgets , но я не могу понять, что передать в качестве третьего параметра (типа FILE*). Пробовал stdin , но он не блокируется.

Как я могу принять ввод от пользователя, используя Objective-C, и в то же время позволить пользователю просто нажать Enter, не заставляя ничего вводить? Как мне прочитать одну строку, даже если эта строка пуста?

Ответы [ 4 ]

5 голосов
/ 22 февраля 2010

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

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

Решение состоит в том, чтобы просто выполнить часть игнорирования самостоятельно, а затем вызвать fgets:

#include <stdio.h>
#include <string.h>

FILE* ignoreline(FILE* stream) {
  for (int c; (c = fgetc(stream)) != EOF;) {
    if (c == '\n') break;
  }
  return stream;
}

void example_use() {
  char buf[1000];
  ignoreline(stdin);
  fgets(buf, sizeof buf, stdin);
  // or, since it returns the stream, can be more compact:
  fgets(buf, sizeof buf, ignoreline(stdin));
}

int main() { // error handling omitted
  int n;
  printf("Enter a number: ");
  scanf("%d", &n);

  char buf[1000];
  printf("Enter a line: ");
  ignoreline(stdin); // comment this line and compare the difference
  fgets(buf, sizeof buf, stdin);
  *strchr(buf, '\n') = '\0';
  printf("You entered '%s'.\n", buf);

  return 0;
}

Обратите внимание, что также распространено и рекомендуется "соединять" линию игнорирования со scanf (или другим входом, не основанным на строках), чтобы превратить это в ввод на строковой основе. В этом случае вы можете изменить его, чтобы вы могли определить разницу между вводом «42 abc» и «42» (в случае «Введите число»). Некоторые люди просто используют fgets везде, а затем анализируют эту строку с помощью sscanf, и хотя это работает, в этом нет необходимости.

3 голосов
/ 25 мая 2011

я использую getch(); в библиотеке conio.h просто программа ожидает нажатия любой клавиши

1 голос
/ 16 августа 2012

используйте getchar() для ввода без использования функции scanf ...

1 голос
/ 23 февраля 2010

Если вы используете Windows, вы можете использовать функцию ReadConsoleInput (подробнее об этом см. В MSDN):

INPUT_RECORD keyin;
DWORD r;

    while (ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE),&keyin,1,&r)) {

    if (keyin.EventType!=KEY_EVENT) continue;
    if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_SPACE) break;    ///use these VK codes to get any key's input

    if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_F1)            
    {
       printf("You pressed F1\n");
    }

    if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_F2)            
    {
        printf("You pressed F2\n",);
    }

    }//end while loop

Тебе не нужно нажимать клавишу ввода после каждой клавиши. Это работает для меня как сон ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...