Страницы

Поиск по вопросам

воскресенье, 8 марта 2020 г.

Обработка строки даты

#cpp #строки


Пользователь вводит дату в формате 01/02/17, нужно сохранить дату в трёх переменных
int соответственно-day,month,year. Я разбивал строку с датой на 3 подстроки и переводил
в каждую в int. Мне кажется-не самый лучший способ. Есть ли како-то более удачное решение
для такой обработки?
    


Ответы

Ответ 1



Можно и удобно регэкспами: #include #include std::vector GetDigitDate(const std::string Date) { std::regex Rx("^(\\d{1,2})/(\\d{1,2})/(\\d{2}|\\d{4})$"); std::smatch Match; if(!(std::regex_match(Date, Match, Rx) && (Match.size()==4))) throw std::runtime_error(""); return {std::stoi(Match[1]),std::stoi(Match[2]),std::stoi(Match[3])}; } int main() { try { std::vector T = GetDigitDate("1/07/2011"); for(const auto &i:T) std::cout << i << std::endl; } catch(...) { std::cout << "Что-то не так!" << std::endl; } return 0; } Естественно, при желании, можно дополнить проверку корректности дней, месяцев и годов. В коде - простейшая проверка просто на числа. ADD: Если не нравится возврат вектора, в качестве результата, небольшая модификация кода, но для C++1z #include #include std::tuple GetDigitDate(const std::string Date) { std::regex Rx("^(\\d{1,2})/(\\d{1,2})/(\\d{2}|\\d{4})$"); std::smatch Match; if(!(std::regex_match(Date, Match, Rx) && (Match.size()==4))) throw std::runtime_error(""); return {std::stoi(Match[1]),std::stoi(Match[2]),std::stoi(Match[3])}; } int main() { try { auto [d,m,y] = GetDigitDate("1/07/2011"); std::cout << "d: " << d << " m: " << m << " y: " << y << std::endl; } catch(...) { std::cout << "Что-то не так!" << std::endl; } return 0; }

Ответ 2



Вариант, который использует QDate::fromString() из Qt: #include #include int main(int argc, char* argv[]) { const char* date_string = (argc == 2) ? argv[argc-1] : "01/02/17"; QDate d = QDate::fromString(date_string, "dd/MM/yy"); d = d.addYears(100); // 19yy -> 20yy int year, month, day; d.getDate(&year, &month, &day); qDebug() << year << month << day; return !year; // if the year is zero; the date is invalid } Код автоматически проверяет, что введённая дата является корректной (кол-во дней в месяце, високосные годы, итд). Пример: $ ./parse-date 5/10/14 2014 10 5 Двузначный год интерпретируется всегда как 19yy, поэтому 00 (2000) не распознаётся как високосный год (важно для 2000-02-29).

Ответ 3



А почему не воспользоваться просто scanf? Эта функция и в C++ работает: int day, month, year; if (sscanf("01/02/17","%d/%d/%d",&month,&day,&year) == 3) { printf("Date is %02d.%02d.%d\n",day,month,year+2000); }

Комментариев нет:

Отправить комментарий