Суть программы в том, что пользователь вводит строку, которая посимвольно считывается и выводится на экран.
Реализована обработка ctrl+c, в результате которой пользователь выбирает, завершить ли программу. Если он хочет продолжить работу, то выводится строка "Продолжение ввода...", и функция close_handler(int sig) завершается. Функция cin.get() ожидает ввода, следовательно в потоке нет мусорных символов, но ввод происходит неправильно
Вопрос: почему после обработки ctrl+c данные не считываются правильным образом?
Пример правильной работы:
ввод: abcde
вывод: abcde
Пример неправильной работы:
ввод: ctrl+c
вывод: Вы уверены, что хотите выйти? Введите YES, чтобы завершить программу
ввод: no
вывод: Продолжение ввода...
ввод: abcde
вывод: de
Ожидаемое поведение:
ввод: ctrl+c
вывод: Вы уверены, что хотите выйти? Введите YES, чтобы завершить программу
ввод: no
вывод: Продолжение ввода...
ввод: abcde
вывод: abcde
#include <iostream>
#include <signal.h>
using namespace std;
void print_str()
{
cout << "Введите строку: " << endl << endl;
string str;
char c = cin.get();
while (c != '\n')
{
str += c;
c = cin.get();
}
cout << str << endl;
}
void close_handler(int sig){
cout << "Вы уверены, что хотите выйти? Введите YES, чтобы завершить программу" << endl;
string ans;
char c = cin.get();
while (c != '\n')
{
ans += c;
c = cin.get();
}
if (ans == "YES")
exit(0);
else
cout << "Продолжение ввода..." << endl;
}
int main() {
signal(SIGINT, close_handler);
print_str();
return 0;
}
Ссылка на код: https://repl.it/@DmitriiNiechipo/stackoverflow-question-0
С точки зрения С++ в обработчике сигнала нельзя работать ни с одним объектом со статическим временем хранения кроме объектов типа std::atomic
. Это включает в том числе объекты стандартных потоков std::cin
и std::cout
. В противном случае это UB.
Также в обработчике сигнала нельзя пользоваться функциями стандартной библиотеки окромя следующих:
std::abort()
std::_Exit()
std::quick_exit()
std::signal() // только для того же сигнала
В С++17 этот список немного расширили, но принципиально ничего не поменялось. Так что вводом-выводом пользоваться всё равно будет нельзя.
Другими словами, всё что можно сделать в обработчике сигнала — это установить какой-либо флаг std::atomic
и/или завершить программу. В конкретных ОС можно сделать немного больше, но ограничения всё равно довольно строгие.
См. Подробности на cppreference.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть задание "Образовать строку из исходной, повторив 1-й и элемент 1 раз, 2-й элемент 2 раз, 3 и элемент – 3 раза и тд" на с++ с ассемблерными вставками
Пишу класс для работы с матрицамиУказатель и кол-во строк и столбцов сокрыто, это понятно