Добре известно е, че cin не е безопасен за тип (напр. cin >> цяло число; и въвеждането на "петдесет и пет" ще доведе до прелитане). Виждал съм много не толкова елегантни начини за предаване на това, като getlining на низ и използване на sstream за преобразуването му в число или цикъл с cin.fail() и изчистване на потока и повторно въвеждане и т.н. библиотека или така или иначе да претоварите оператора за извличане, за да направите cin автоматично безопасен за въвеждане?
Как да направите cin typesafe?
Отговори (5)
напр.
cin >> integer;
и въвеждането на "петдесет и пет" ще го накара да се обърне
Не, това няма да го накара да се „откачи“; това ще доведе до задаване на състояние на грешка на потока, точно както при всеки друг поток. Това не означава, че std::cin
не е безопасен за тип.
Една опция за обработка на грешки при четене от поток би била да се напише шаблон на функция, който изпълнява извличането, тества дали е успешно, нулира състоянието на грешка в потока, ако е подходящо, и връща дали извличането е успешно заедно с резултата.
Добре известно е, че cin не е безопасен за тип (напр. cin >> цяло число; и въвеждането на "петдесет и пет" ще доведе до изключване).
Типовата безопасност не означава това, което си мислите, че означава. "петдесет и пет" е низ. Да го конвертирате безопасно в число е сложен проблем, ако наистина искате да имате обща/преносима реализация (ами ако е „cinquante-cinq“ [френски] или „femtifem“ [норвежки])? Ще трябва да отчетете езика, лексикалния анализ, граматическата коректност и така нататък. Това е далеч извън обхвата на STL.
std::istream
е безопасен за типове в смисъл, че ако опитате примера, който сте дали, потокът ще разпознае грешката („знае“, че не може да интерпретира потока като цяло число) и ще сигнализира на клиентския код за грешката по начин, който може да бъде проверен и обработен в клиентския код.
За сравнение, ако използвате int i; sscanf("fifty five", "%s", &i);
, това вероятно няма да доведе до грешка, напълнете вашия i
с боклук и програмата ви може да се срине по-късно, ако зависи от това i
да има валидна стойност (може да греша в това - не съм използвал sscanf
още от гимназията или нещо такова). Алтернативно, това може да повреди паметта на вашата програма, ако имате заявка за формат, която не съответства на съдържанието на вашия входен низ.
напр. cin >> цяло число; и въвеждането на "петдесет и пет" ще го накара да се откачи
[...]
Има ли някаква библиотека или все пак да претоварите оператора за извличане, за да направите cin автоматично безопасен за въвеждане?
Така че std::cin
се проваля, когато искате да прочетете грешен обект от него.
Странно, тук винаги съм смятал, че фактът, че четенето се проваля, ако се опитате да прочетете грешен тип, е това, което го прави безопасен за тип< /em>.
Както и да е, тъй като случайно не сте съгласни, какво поведение бихте предложили вместо това?
Можете да имате структура с поле „Тип“ и поле за обединение, съдържащо низ, double, bool и int. След това можете да напишете оператор >> (ostream &, youtype &) overload, който първо чете низа от ostream и се опитва да го преобразува в най-специфичния тип ("1" става int, "1.0" двойно и т.н. ... ), като зададете полето „Тип“ съответно.
Това не би било идеално решение, но трябва да бъде сравнително лесно за повторно използване в други проекти.
Обработка на изключения. Това ще попречи на примера ви да се „обърне [ping] out“.