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

417
04 февраля 2017, 09:21

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

Answer 1

Можно и удобно регэкспами:

#include <iostream>
#include <regex>
std::vector<int> 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<int> 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 <iostream>
#include <regex>
std::tuple<int,int,int> 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; 
}
Answer 2

А почему не воспользоваться просто scanf? Эта функция и в C++ работает:

int day, month, year;
if (sscanf("01/02/17",&month,&day,&year) == 3)
{
    printf("Date is %02d.%02d.%d\n",day,month,year+2000);
}
Answer 3

Вариант, который использует QDate::fromString() из Qt:

#include <QDate>
#include <QDebug>
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).

READ ALSO
Динамическое выделение памяти с++

Динамическое выделение памяти с++

Вопрос заключается в необходимости оператора newОн предназначается для динамического выделения памяти, то есть во время выполнения программы,...

457
Ошибка преобразования char в int

Ошибка преобразования char в int

Имеется следующий код:

400
распознавание четырехугольников в OpenCV

распознавание четырехугольников в OpenCV

Работаю над распознаванием фигур в OpenCVЧтобы найти четырехугольник, смотрю на количество вершин:

542