Как я могу сказать, что моя структура оставлена ​​в неверном состоянии?

Это вопрос о неверном вводе, не неверное форматирование. Для примера приведен следующий код:

tm bar;

foo >> get_time(&bar, "%Y-%m-%d");

cout >> bar.tm_year >> bar.tm_mon >> bar.tm_mday >> endl;

Это хорошо, если я определю: stringstream foo("2001-02-28 non-leap year"); И имеет явную ошибку, если у меня есть недопустимый формат, такой как: stringstream foo("bad format 2001-02-28 non-leap year");

Но я не знаю, как определить, был ли мой ввод недействительным, например:

stringstream foo("2001-02-30 non-leap year");

В этом случае bar можно читать, как будто ничего не случилось. Могу ли я прослушать что-то, что предупредит меня о том, что ввод был неверным?

3

Решение

поскольку mktime пытается интерпретировать также значения вне допустимого диапазона (т.е. для 2001-02-30 будет интерпретироваться как 2001-03-01), вы можете сделать mktime с последующим localtime, если вы получите разные значения обратно, это означает, что исходные значения были недействительными.

2

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

Как упоминается Matteo Italiaответ, кроме написания собственного григорианского валидатора, ваша единственная надежная двойная проверка mktime. tmполучено с get_time не может быть проверено, так как поля могут и не могут быть заполнены. Рассмотрим следующие 2 неверных примера:

Делая это: istringstream("2001-02-30") >> get_time(&bar, "%Y-%m-%d"); приводит к результату, который было бы изменить при тщательном запуске mktime:

bar.tm_mday : 30
bar.tm_mon : 1
bar.tm_year : 100

Делая это: istringstream("2001-13-30") >> get_time(&bar, "%Y-%m-%d"); приводит к результату, который не будет изменить, когда пробежать mktime:

bar.tm_mday : 30
bar.tm_mon : 0
bar.tm_year : 100

Чтобы все недействительные даты были изменены mktime нам нужно прочитать дату без использования get_time:

int year;
int month;
int day;
istringstream foo("2000-13-30");

foo >> year;
foo.ignore();
foo >> month;
foo.ignore();
foo >> day;

tm bar = { 0, 0, 0, day, month - 1, year - 1900 };

На данный момент любая ошибка в bar может быть исправлено mktime поэтому наш действительный шаг проверки будет состоять в проверкеtime_t(-1) вернуть и сравнить измененный bar назад к исходным значениям:
if(time_t(-1) != mktime(&bar) && bar.tm_mday == day && bar.tm_mon == month - 1 && bar.tm_year == year - 1900) если это условие истинно, то вход bar был действительным.

В заключение можно подтвердить tm без написания григорианского валидатора, но это не можно проверить tm это было прочитано get_time,

0

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