Почему у меня есть исключение при создании регулярного выражения в VS2015?

У меня есть исключение в этом коде

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.

0

Решение

Ваше исключение случается не при построении регулярного выражения, а когда вы бросаете свое собственное.

Сначала вы проверяете, что длина вашей строки ровно 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 символов?

1

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

Других решений пока нет …

По вопросам рекламы [email protected]