Как я могу обработать исключение недопустимого типа данных и остановить выполнение программы?

У меня проблема, я изучаю исключения и видимо что-то не так понял.

int n;
try {
  cout << "enter value: " << endl;
  cin >> n;
}
catch (exception& ex) {
  cerr << ex.what();
}
cout << n;

Вывод для любого символьного литерала: Вывод самого литерала и ноль.

Я хочу понять, если пользователь вводит неверный тип данных, могу ли я как-то обработать этот ввод исключением и сказать пользователю, что он вводит текст, а не число? Как я могу понять, где происходит исключение? Как с помощью обработки остановить выполнение программы, иначе программа продолжает выполнять инструкции...

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

также я попробовал этот код

cout << "enter value: " << endl;
cin >> n;
if (!cin) throw exception();
try {
    cout << n;
}
catch (exception& ex) {
    cerr << ex.what();
}

Чтобы его можно было поймать, throw должен находиться внутри try { }. И нет, cin обычно не выдает ошибку при недопустимом вводе, вместо этого он прекращает чтение и устанавливает для себя условие ошибки.

BoP 22.07.2024 19:56

«Символовый литерал» — это то, что вы пишете в исходном коде: например, 'a'. Предположительно, ввод, вызывающий проблемы, не является цифровым символом.

Pete Becker 22.07.2024 20:02

Примечание: после подсказки в этом нет необходимости. std::endl и std::cout связаны; экстрактор потока (std::cin) сначала сбрасывает std::cin >> n, поэтому приглашение будет отображаться без принудительного его выполнения.

Pete Becker 22.07.2024 20:03

Re: «ввод текста, а не числа» — весь ввод пользователя представляет собой текст, а не число. Проблема в том, что текст начинается с нецифрового символа, поэтому его нельзя преобразовать в число.

Pete Becker 22.07.2024 20:05

Обычный путь здесь не предполагает исключений. Просто повторяйте цикл, пока ввод не станет действительным: while (!std::cin >> n) { /* clean up and prompt for new input */ }.

Pete Becker 22.07.2024 20:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
84
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

вам следует проверить наличие ошибок в коде внутри блока try.

на основе вашего кода (похоже, вы используете std и endl)

код будет:

try {
    std::cout << "Enter value \n";
    std::cin >> value;
    if (std::cin.fail())
       throw (/*what ever error you want*/);
    /*
     or 
     if (std::cin.fail())
       throw std::invalid_argument("your error text");
    */

}
catch(const char *e){
    std::cerr << "ERROR " << e << '\n';
    std::cin.clear();
    // send user to try for new input as you want
}
/*
catch(const std::invalid_argument &err)
{
    std::cerr << err.what() << '\n'; 
}
*/
  • Рекомендуется не использовать пространство имен std.
  • Использование endl немного медленное, поэтому использование '\n' ускорит ваш код.

Также рекомендуется не использовать исключения таким образом. В качестве упражнения это нормально, но в реальном коде исключения не следует использовать для обычного управления потоком данных. Они используются, когда код, обнаруживающий проблему, не может ее решить.

Pete Becker 22.07.2024 21:17

@PeteBecker Конечно, но поскольку ОП хочет использовать try-catch, я написал правильную форму этого кода.

Mahdy.n 22.07.2024 21:28

Незначительная деталь: throw (/*what ever error you want*/); конфликтует с catch(const char *e). catch слишком конкретен. Я рекомендую выполнить оба сопоставления, а это будет означать передачу указателя на c-строку.

user4581301 23.07.2024 01:07

Обычно потоки не имеют маски исключений, установленной по умолчанию. Но вы можете установить нужную маску вручную, чтобы включить срабатывание исключений (например, когда установлен failbit), например так:

#include <iostream>

int main()
{
    int n{};
    try
    {
        std::cin.exceptions(std::ios_base::failbit);
        std::cout << "Enter value:\n";
        std::cin >> n;
        std::cout << "Got " << n << '\n';
    }
    catch (const std::ios_base::failure& err)
    {
        std::cerr << "Caught " << err.what() << '\n';
    }
}

Однако обратите внимание: если после допустимого числового значения во входных данных есть какой-то мусор, оператор >> просто извлечет это значение и остановится (без сбоя). Сбой произойдет только в том случае, если в начале нет допустимого числового значения (игнорируя пробелы).

Другие вопросы по теме

Как я могу настроить оповещение или звуковой сигнал в случае поломки моего кода? (В идеале на Python)
CsvHelper не может найти заголовок столбца, которого нет
Почему исключение «Exception», похоже, не перехватывает исключение?
«Exception.Exception(SerializationInfo, StreamingContext)» устарело» – лучшая практика реализации исключений?
Неожиданное поведение генератора, если он не назначен переменной
Как использовать try-catch (IOException) для BufferedWriter.write, вложенного в if-else?
Где следует создавать исключения в шестиугольной архитектуре?
Как вернуть пользовательское сообщение об ошибке для неверного значения перечисления в Spring Boot RequestBody?
Как написать устойчивый объектно-ориентированный метод для таблицы обновления SQL с повтором в catch
Где из стандарта я прочитал, что исключения производного класса, хранящиеся по ссылке на базовый класс, отсекаются при обнаружении?