У меня есть исключение в этом коде
Date & Date::operator=(const std::string & str){
if (str.size() != 10)
throw std::exception("not a date");std::regex r;// exception here
try { // exception here
std::regex regEx ("^[0-9]{4}[0-9]{2}[0-9]{2}");
}
catch (std::exception &e) {
e.what();
}
std::regex delims("([^.,;-]+)");
std::smatch match;
if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
std::stringstream ss;
std::string tmp(match.str());
std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(ss, "\n"));
ss >> year;
ss >> month;
ss >> day;
}
return *this;
}
Если я помещаю подобный код в основную функцию, то работает нормально.
Я использую Visual Studio 2015 Community Edition.
Ваше исключение случается не при построении регулярного выражения, а когда вы бросаете свое собственное.
Сначала вы проверяете, что длина вашей строки ровно 10 символов.
Если вы поместите строку размером 10 в вашу строку, все будет работать как надо:
int main()
{
std::string str = "20151107AB";
int year = 0;
int month = 0;
int day= 0;
if (str.size() != 10)
throw std::exception("not a date");
std::regex regEx("^[0-9]{4}[0-9]{2}[0-9]{2}");
std::regex delims("([^.,;-]+)");
std::smatch match;
if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
std::stringstream ss;
std::string tmp(match.str());
std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(ss, "\n"));
ss >> year;
ss >> month;
ss >> day;
}
}
Если вы удалите «AB», вы получите ошибку, как описано в вашем вопросе.
int main()
{
std::string str = "20151107";
int year = 0;
int month = 0;
int day= 0;
if (str.size() != 10)
throw std::exception("not a date");
std::regex regEx("^[0-9]{4}[0-9]{2}[0-9]{2}");
std::regex delims("([^.,;-]+)");
std::smatch match;
if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
std::stringstream ss;
std::string tmp(match.str());
std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(ss, "\n"));
ss >> year;
ss >> month;
ss >> day;
}
}
Если вы сейчас удалите длину, проверьте, что все снова работает как надо.
int main()
{
std::string str = "20151107";
int year = 0;
int month = 0;
int day= 0;
std::regex regEx("^[0-9]{4}[0-9]{2}[0-9]{2}");
std::regex delims("([^.,;-]+)");
std::smatch match;
if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
std::stringstream ss;
std::string tmp(match.str());
std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(ss, "\n"));
ss >> year;
ss >> month;
ss >> day;
}
}
Кроме того, если вы поймаете исключение, все будет в порядке (хотя код не выполняется)
int main()
{
try
{
std::string str = "20151107";
int year = 0;
int month = 0;
int day = 0;
if (str.size() != 10)
throw std::exception("not a date");
std::regex regEx("^[0-9]{4}[0-9]{2}[0-9]{2}");
std::regex delims("([^.,;-]+)");
std::smatch match;
if (std::regex_match(str.cbegin(), str.cend(), match, regEx)) {
std::stringstream ss;
std::string tmp(match.str());
std::copy(std::sregex_token_iterator(tmp.cbegin(), tmp.cend(), delims, -1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(ss, "\n"));
ss >> year;
ss >> month;
ss >> day;
}
}
catch (std::exception& e)
{
//handle
}
}
Поэтому я предполагаю, что вы нигде не поймаете исключение, что может привести к повреждению памяти, поскольку стандарт не определяет, нужно ли в этом случае разматывать этот стек.
Я бы порекомендовал
1. читать Имеет ли смысл отлавливать исключения в основном (…)?
2. правильно поймать исключение, выданное Date::operator=
Может быть, вы также хотите установить глобальный обработчик исключений (для безопасного завершения вашей программы).
И еще одна вещь: почему вы проверяете длину вашей строки даты ровно 10, когда вам нужно всего 8 символов?
Других решений пока нет …