обработка ошибок — проверка допустимого целочисленного ввода в переполнении стека

так что я видел, что многие люди спрашивают об этом, а не много твердых ответов, плавающих в сети. большинство из них просто проверяют, что вместо строки было помещено целое число, но если было введено число с плавающей запятой, оно усекает нижнюю половину или, если целые числа и символы являются целыми, оно усекает символы. Мне нужна помощь в написании фрагмента кода, который проверяет ввод пользователя и просит пользователя повторить попытку, если его ввод недопустим или комбинация допустимый / недействительный. я думаю, что основная идея заключалась в том, чтобы сделать строку, чтобы она принимала что-либо, затем использовать sstream для манипулирования и затем возвращаться к int, если ввод был допустимым, но мне не удалось проверить другие части. если кто-то сталкивается с этим или может помочь мне, пожалуйста, свяжите меня с этим. я опубликую свой код, когда получу хорошее представление о том, что делать.

0

Решение

Предполагая, что вы не можете использовать boost::lexical_castВы можете написать свою собственную версию:

#include <sstream>
#include <iostream>
#include <stdexcept>
#include <cstdlib>
template <class T1, class T2>
T1 lexical_cast(const T2& t2)
{
std::stringstream s;
s << t2;
T1 t1;
if(s >> std::noskipws >> t1 && s.eof()) {
// it worked, return result
return t1;
} else {
// It failed, do something else:
// maybe throw an exception:
throw std::runtime_error("bad conversion");
// maybe return zero:
return T1();
// maybe do something drastic:
exit(1);
}
}int main() {
std::string smin, smax;
int imin, imax;

while(std::cout << "Enter min and max: " && std::cin >> smin >> smax) {
try {
imin = lexical_cast<int>(smin);
imax = lexical_cast<int>(smax);
break;
} catch(std::runtime_error&) {
std::cout << "Try again: ";
continue;
}
}

if(std::cin) {
std::cout << "Thanks!\n";
} else {
std::cout << "Sorry. Goodbye\n";
exit(1);
}
}
2

Другие решения

Вы можете использовать C ++ 11 функции преобразования строк как стол

try
{
std::string value = ...;
long number = std::stol(value);
}
catch (std::invalid_argument const& e)
{
// no conversion could be performed
}

Обновление после комментариев: Visual C ++ 11 поставляется с реализациями Visual Studio 2012 std::stol в качестве удобной обертки вокруг strtol объявлено в <cstdlib>, Я думаю, что можно с уверенностью предположить, что большинство реализаций C ++ 11 определяют его наиболее оптимальным способом, не достигая std::stringstream техника.

2

Функция C strtol (и это братья и сестры) сможет сказать вам, если строка, поданная к нему, полностью израсходована.

 std::string str;
char *endptr;
std::cin >> str;
long x = std::strtol(str.c_str(), &endptr, 0);
if (*endptr != 0)
cout << "That's not a valid number...";
1

Я не знаю, есть ли какие-нибудь классы в стандартной c ++ lib, которые инкапсулируют примитивные типы, как в java, но вот как бы выглядела простая и очень базовая реализация

class Integer {
private:
int value;
void parse(string);
public:
Integer(string);
int intValue();
};

Integer::Integer(string sint) { parse(sint); }
int Integer::intValue() { return value; }

void Integer::parse(string sint) {
string::iterator its = sint.begin();
while(its != sint.end() && (! (*its < '0' || *its > '9'))) {
its++;
}
if(its != sint.end()) {
throw sint + ": Input is not a valid integer.";
}
value = atoi(sint.c_str());
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector