Игнорировать клавишу возврата на стандартный ввод

Я хочу создать программу, которая заставляет пользователя вводить текст, но не позволяет ему стирать его, какой простой способ сделать это на C?

Единственное, что у меня есть, это (c = getchar()) != EOF && c != '\b', которое не работает. Любые идеи?


person Iceland_jack    schedule 02.07.2010    source источник


Ответы (3)


POSIX-версия для Unix

#include <sys/types.h>        
#include <termios.h>
#include <stdio.h>
#include <string.h>

int
 main()
{

         int fd=fileno(stdin);
         struct termios oldtio,newtio;
         tcgetattr(fd,&oldtio); /* save current settings */
         memcpy(&newtio, &oldtio, sizeof(oldtio));
         newtio.c_lflag = ICANON;
         newtio.c_cc[VERASE]   = 0;     /* turn off del */
         tcflush(fd, TCIFLUSH);
         tcsetattr(fd,TCSANOW,&newtio);
         /* process user input here */

         tcsetattr(fd,TCSANOW,&oldtio);  /* restore setting */
         return 0;        
}
person jim mcnamara    schedule 02.07.2010
comment
+1. Я не понимаю, что в приготовленном режиме можно отключить только некоторые клавиши. - person Dummy00001; 02.07.2010
comment
Это неполное. Вам также необходимо отключить ^U, иначе пользователь все равно сможет стереть всю ожидающую строку. Также ^В. Может быть больше; Проверьте. Более безопасным подходом было бы полное отключение режима ICANON. - person R.. GitHub STOP HELPING ICE; 03.07.2010
comment
Р. - Вы правы. Спецификации OP не включали это, ИМО. И вам нужно будет прочитать всю структуру termios, отключив возможности, верно? Как упоминалось в другом месте, полное решение - это не то, что я опубликовал. - person jim mcnamara; 03.07.2010

Вы не можете сделать это с переносимым кодом - по сути, каждая ОС имеет какую-то минимальную буферизацию/редактирование, встроенную в стандартный поток ввода.

В зависимости от операционных систем, на которые вам нужно ориентироваться, есть хорошее изменение: у вас будет getch, который будет выполнять небуферизованное чтение. В Windows вы включаете <conio.h> и делаете это. В большинстве Unix вам нужно включить (и связать) curses (или ncurses) для него.

person Jerry Coffin    schedule 02.07.2010
comment
Неправильно насчет проклятий. Смотрите принятый ответ. Это очень просто и портативно (POSIX). - person R.. GitHub STOP HELPING ICE; 03.07.2010
comment
@R: Я посмотрел на это. Я еще не уверен, что это правильно, и проклятия определенно намного проще. - person Jerry Coffin; 03.07.2010

Это, вероятно, сложнее, чем вы себе представляете. Для этого вам, вероятно, потребуется взять на себя управление отображением символов, которые вводит пользователь, и т. д.

Загляните в библиотеку curses. Функция wgetch должна быть тем, что вам нужно, но сначала вам нужно инициализировать curses и т. д. Прочтите справочные страницы — если вам повезет, вы найдете справочные страницы ncurses или curses-intro. Вот фрагмент:

   To  initialize  the  routines,  the  routine initscr or newterm must be
   called before any of the other routines  that  deal  with  windows  and
   screens  are  used.   The routine endwin must be called before exiting.
   To get character-at-a-time input  without  echoing  (most  interactive,
   screen  oriented  programs want this), the following sequence should be
   used:

         initscr(); cbreak(); noecho();

   Most programs would additionally use the sequence:

         nonl();
         intrflush(stdscr, FALSE);
         keypad(stdscr, TRUE);

Если у вас нет этой справочной страницы / для получения дополнительной информации, просмотрите справочные страницы отдельных функций.

person asc99c    schedule 02.07.2010