@kostyakos52000
student

Ошибка в блоке try-catch, почему возникает данная проблема? Как исправить баг?

описание ошибки

сделана проверка на дурака на ввод целых чисел, однако при вводе строки, которая начинается с цифры возникает данный баг, в других случаях всё работает
5cd874f807892531920262.jpeg5cd8768b8c0df746590847.jpeg
проблемный участок кода
int inp_int()
{
	int number; 
	cout << "Введите целое число: ";
	try
	{
		cin >> number;
		if (cin.fail())
			throw NULL;
	}
	catch (...)
	{
		cin.clear(); // очистка состояния потока
		//while (cin.get() != '\n'); // из потока извлекаются символы, пока не будет конец введенной строки
		cin.ignore(INT_MAX, '\n');
		cout << "Ошибка типа. ";
		return inp_int();
	}
	return number;
}
int main()
{
	setlocale(LC_ALL, "rus");
	enum operations { adding = 1, printing, printing_by_num, printing_by_dest };
	TREE *tree = NULL;
	int choice = NULL;
	while (choice != 5)
	{
		cout << "\tchoose" << endl
			<< " 1 - add note" << endl
			<< " 2 - show tree" << endl
			<< " 3 - show train info by number" << endl
			<< " 4 - show train info by destination name" << endl
			<< " 5 - exit" << endl;
		choice = inp_int();
		DATA temp;
		string str;
		unsigned long num;
		switch (choice)
		{
		case adding:
			cout << "destination = ";
			cin >> temp.destination;
			cout << "number = ";
			temp.number = inp_int();
			cout << "time(xx yy) = ";
			cin >> temp.hours >> temp.minutes; //добавить защиту!!!
			add_node(temp, tree);
			break;
		case printing:
			show(tree);
			break;
		case printing_by_num:
			cout << "num = ";
			num = inp_int();
			show(tree, num);
			break;
		case printing_by_dest:
			cout << "str = ";
			cin >> str;
			show(tree, str);
			break;
		default:
			cout << "here is no such option" << endl;
			break;
		}
	}
	system("Pause");
	return 0;
}

полный код программы
#include <iostream>
#include <string>

using namespace std;

//info struct
struct DATA
{
	unsigned long number;
	string destination;
	int hours;
	int minutes;
};
//main tree struct
struct TREE {
	DATA data;
	TREE *left;
	TREE *right;
};
//tree printing funcs
void show(TREE *&Tree)              //Функция обхода
{
	if (Tree != NULL)               //Пока не встретится пустое звено
	{
		show(Tree->left);               //Рекурсивная функция для вывода левого поддерева
		cout << "train " << Tree->data.number << " to " << Tree->data.destination << " moves in " << Tree->data.hours << ':' << Tree->data.minutes << endl;
		show(Tree->right);               //Рекурсивная функци для вывода правого поддерева
	}
}
void show(TREE *&Tree, unsigned long condition)              //Функция обхода
{
	if (Tree != NULL)               //Пока не встретится пустое звено
	{
		if (condition == Tree->data.number)
			cout << "train " << Tree->data.number << " to " << Tree->data.destination << " moves in " << Tree->data.hours << ':' << Tree->data.minutes << endl;
		else if (condition > Tree->data.number)
			show(Tree->right);               //Рекурсивная функци для вывода правого поддерева
		else
			show(Tree->left);               //Рекурсивная функция для вывода левого поддерева
	}
}
void show(TREE *&Tree, string condition)              //Функция обхода
{
	if (Tree != NULL)               //Пока не встретится пустое звено
	{
		show(Tree->left);               //Рекурсивная функция для вывода левого поддерева
		if (condition == Tree->data.destination)
			cout << "train " << Tree->data.number << " to " << Tree->data.destination << " moves in " << Tree->data.hours << ':' << Tree->data.minutes << endl;
		show(Tree->right);               //Рекурсивная функци для вывода правого поддерева
	}
}
//tree building
void add_node(DATA data, TREE *&MyTree) //Фукция добавления звена в дерево
{
	//NaN
	if (NULL == MyTree)             //Если дерева нет, то ложим семечко
	{
		MyTree = new TREE;          //Выделяем память под звено дерева
		MyTree->data = data;              //Записываем данные в звено
		MyTree->left = MyTree->right = NULL; //Подзвенья инициализируем пустотой во избежание ошибок
	}
	if (data.number == MyTree->data.number)
	{
		cout << "train with this number is already exist" << endl;
		//return;
	}
	//<
	if (data.number < MyTree->data.number)   //Если нововведенный элемент x меньше чем элемент x из семечка дерева, уходим влево
	{
		if (MyTree->left != NULL) add_node(data, MyTree->left); //При помощи рекурсии заталкиваем элемент на свободный участок
		else          //Если элемент получил свой участок, то
		{
			MyTree->left = new TREE;                 //Выделяем память левому подзвену. Именно подзвену, а не просто звену
			MyTree->left->left = MyTree->left->right = NULL;   //У левого подзвена будут свои левое и правое подзвенья, инициализируем их пустотой
			MyTree->left->data = data;                     //Записываем в левое подзвено записываемый элемент
		}
	}
	//>
	else if (data.number > MyTree->data.number)              //Если нововведенный элемент x больше чем элемент x из семечка дерева, уходим вправо
	{
		if (MyTree->right != NULL) add_node(data, MyTree->right); //При помощи рекурсии заталкиваем элемент на свободный участок
		else              //Если элемент получил свой участок, то
		{
			MyTree->right = new TREE;                 //Выделяем память правому подзвену. Именно подзвену, а не просто звену
			MyTree->right->left = MyTree->right->right = NULL;   //У правого подзвена будут свои левое и правое подзвенья, инициализируем их пустотой
			MyTree->right->data = data;                     //Записываем в правое подзвено записываемый элемент
		}
	}
}
// input protection functions
int inp_int()
{
	int number; //init
	cout << "Введите целое число: ";
/*	while (!(cin >> number))
	{
		cin.clear(); // очистка состояния потока
		while (cin.get() != '\n'); // из потока извлекаются символы, пока не будет конец введенной строки
		cout << "Ошибка. Введите целое число: ";
	}
	return number;*/
	try
	{
		cin >> number;
		if (cin.fail())
			throw NULL;
	}
	catch (...)
	{
		cin.clear(); // очистка состояния потока
		//while (cin.get() != '\n'); // из потока извлекаются символы, пока не будет конец введенной строки
		cin.ignore(INT_MAX, '\n');
		cout << "Ошибка типа. ";
		return inp_int();
	}
	return number;
}
int main()
{
	setlocale(LC_ALL, "rus");
	enum operations { adding = 1, printing, printing_by_num, printing_by_dest };
	TREE *tree = NULL;
	int choice = NULL;
	while (choice != 5)
	{
		cout << "\tchoose" << endl
			<< " 1 - add note" << endl
			<< " 2 - show tree" << endl
			<< " 3 - show train info by number" << endl
			<< " 4 - show train info by destination name" << endl
			<< " 5 - exit" << endl;
		choice = inp_int();
		DATA temp;
		string str;
		unsigned long num;
		switch (choice)
		{
		case adding:
			cout << "destination = ";
			cin >> temp.destination;
			cout << "number = ";
			temp.number = inp_int();
			cout << "time(xx yy) = ";
			cin >> temp.hours >> temp.minutes; //добавить защиту!!!
			add_node(temp, tree);
			break;
		case printing:
			show(tree);
			break;
		case printing_by_num:
			cout << "num = ";
			num = inp_int();
			show(tree, num);
			break;
		case printing_by_dest:
			cout << "str = ";
			cin >> str;
			show(tree, str);
			break;
		default:
			cout << "here is no such option" << endl;
			break;
		}
	}
	system("Pause");
	return 0;
}

  • Вопрос задан
  • 116 просмотров
Пригласить эксперта
Ответы на вопрос 1
@xandox
у тебя происходит следующие:
1) ты вводишь "2a"
2) cin >> number; читает 2, смотрит что следующий символ не цифра и возвращает тебе 2 оставляя "a" в потоке ввода.
3) срабатывает твоя основная логика
4) идет переход к п.1, но в потоке уже есть "a" и по этому cin не дожидается никакого ввода сразу завершается с ошибкой, о чем и сообщает твоя "Ошибка типа"
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы