首页 > 解决方案 > 如何将日期格式从 std::cin 解析为 c++ 中的字符串流缓冲区?

问题描述

有这个类:

日期.hpp

#ifndef DATE_HPP
#define DATE_HPP

#include <time.h>
#include <iostream>
#include <sstream>

class Date
{
    std::stringstream format;
    time_t date;
    struct tm *date_tm;

public:
    Date() : date(time(NULL)), date_tm(localtime(&date)) {}
    Date(std::istream &in);
    Date(std::string str);

    const std::string getDate();
    const bool dateMatch(std::string str);
};

#endif //DATE_HPP

而这个ctors:date.cpp

#include "date.hpp"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <regex>

bool isDate(std::string target)
{
    std::regex reg("[1-12]{2}/[1-31]{2}[00-99]{2}");
    return std::regex_search(target, reg);
}

Date::Date(std::istream &in)
{
    date_tm = new struct tm;
    std::cout << "enter date [mm/dd/yy]: ";
    format.basic_ios::rdbuf(in.rdbuf());

    if (isDate(format.str()))
    {
        format >> std::get_time(date_tm, "%m/%d/%y");
    }
    else
    {
        std::cout << "Format of date is not valid\n";
    }
}
...

如果我尝试使用带std::istream参数的 ctor:

#include "date.hpp"
#include <iostream>

using namespace std;

int main()
{
    Date d(cin);
    cout << d.getDate() << '\n';
}

然后,日期格式检查甚至在我可以写入 cin 之前就失败了。现在有什么问题?

标签: c++regexbufferistream

解决方案


你的格式应该是"%m/%d/%Y". 请参阅:https ://en.cppreference.com/w/cpp/io/manip/get_time 。您的正则表达式也缺少一个'/'. 再加上您的正则表达式数字范围不太正确;它们匹配一个字符类,而不是一个数字。"[1-12]"我认为只匹配一个字符的"1"字符串"2"。你需要对数字范围做一些不同的事情。您可以通过检查是否format.fail()true而不是运行正则表达式来检查日期解析是否失败。另外,我对您的初始化方法持怀疑态度format。我认为,最好只写

std::string s;
std::getline(std::cin, s);
std::stringstream format(s);

.


推荐阅读