Вы должны установить обработчик сигнала. Как минимум добавить
signal(SIGINT, my_signal_handler);
внутри вашего main
перед while(running)
, но лучше использовать подпись(2).
Вы также должны знать, что stdio выполняет буферизацию; обычно stdout
буферизуется строкой, когда это терминал (но см. setvbuf(3 ) и друзья). Поэтому вам следует либо вызвать fflush(3) (вероятно, как fflush(NULL);
) перед scanf
внутри цикла или заканчивайте каждую строку управления форматом printf
явным \n
.
Наконец, scanf(3) может дать сбой и возвращает количество отсканированных элементов, которые вы должны протестировать.
Кстати, ваш main
неверен, его следует определить как int main(void)
или, что предпочтительнее, int main(int argc, char**argv)
.
Однако (при условии, что вы работаете в Linux) очень внимательно прочитайте signal(7) (обратите внимание на то, что сказано об обработчиках сигналов и безопасных функциях асинхронных сигналов) и POSIX signal.h
документация и объявите свой флаг running
как
volatile sigatomic_t running;
(или, возможно, в C11 как volatile _Atomic bool running;
)
Очень важен volatile
квалификатор. В противном случае компилятору разрешено оптимизировать (и, например, притвориться, что running
всегда верно).
Обратите внимание, что использование signal(2) часто является плохой идеей. Во-первых, если вам действительно нужна обработка сигналов, вам лучше использовать sigaction(2 )а>. Тогда ваш вызов signal(sig, SIG_IGN);
в вашем случае бесполезен (поскольку флаг volatile running
был бы изменен в обработчике сигнала). Наконец, для мультиплексирования ввода (и вывода) вы можете использовать poll(2 ), который можно использовать для ожидания и проверки наличия каких-либо доступных входных данных для stdin
(на самом деле STDIN_FILENO
, что равно 0), и в более общем плане для реализации циклы событий. Вы можете использовать (вместо poll
, который я настоятельно рекомендую) старый и почти устаревший select(2), но лучше использовать poll( 2)а>. См. также epoll(7) и inotify(7), но, вероятно, они вам не нужны.
Имейте в виду, что в терминалах stdin
часто является tty (проверьте это с помощью isatty( 3)) следуя линейной дисциплине (поэтому происходит некоторая буферизация строк внутри ядра). Прочтите страницу разоблачение tty. Рассмотрите возможность использования библиотеки и функции GNU readline (или, возможно, ncurses), возможно, это то, что вам действительно нужно.
Прочтите также Продвинутое программирование в Linux и возьмите за привычку читать документацию по каждой используемой вами функции.
person
Basile Starynkevitch
schedule
28.06.2016
scanf(%d", &num);
отсутствуют двойные кавычки. - person Basile Starynkevitch   schedule 29.06.2016