头文件data.h的内容为:
#pragma once
#ifndef DATE_H_INCLUDED
#define DATE_H_INCLUDED
#include<iostream>
#include<string>
#include<vector>
#include<stdexcept>
using namespace std;
//编写构造函数,接受一个string日期,
class date
{
public:
friend ostream & operator<<(ostream& out, const date& d);
date() = default;
date(string &ds);
unsigned y() const { return year; }
unsigned m() const { return month; }
unsigned d() const { return day; }
private:
unsigned year, month, day;
};
const string month_name[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
const string month_abbr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" };
const int days[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
inline int get_month(string &ds, int &end_of_month)
{
int i,j;
for (i = 0; i < 12; i++) {
for (j = 0; j < month_abbr[i].size(); j++)
if (ds[j] != month_abbr[i][j])
break;
if (j == month_abbr[i].size())//与月份的简称相同,不小
break;
}
if (i == 12)//12次循环都没找到,出错了
throw invalid_argument("月份不对");
if (ds[j] == ' ') {//for循环中j已经++了
end_of_month = j + 1;//end_of_month为引用,所以要改变调用它的值?为何+1,空白符下一个为p
return i + 1;//下标从0开始的
}
//否则考虑是否是月份全称
for (;j < month_name[i].size(); j++) {
if (ds[j] != month_name[i][j])
throw invalid_argument("月份全称不对");
}
if (ds[j] == ' ') {//全称结束,且其后为空格
end_of_month = j+1;//为何为+1?因p为下一个非空格
return i + 1;
}
else
throw invalid_argument("月份全称过多");
}
inline int get_day(string &ds, int month, int &p)//引入i, p定位用,还要修改,所以用引用
{
size_t q;
int day;
day = stoi(ds.substr(p), &q);
if (day < 1 || day > days[month])
throw invalid_argument("日期错误");
p += q;
return day;
}
inline int get_year(string &ds, int &p)
{
int year;
size_t q;
year = stoi(ds.substr(p), &q);
if (p + q != ds.size())
throw invalid_argument("结尾出错");
return year;
}
date::date(string &ds)
{
int p;
size_t q;
if ((p = ds.find_first_of("0123456789")) == ds.npos)//注意逻辑,不清要加上括号
throw invalid_argument("没有数字");
if (p > 0) {
month = get_month(ds, p);
day = get_day(ds, month, p);
if (ds[p] != ' ' && ds[p] != ',')
throw invalid_argument("月与年之间的间隔符出错");
p++;//去掉间隔符
year = get_year(ds, p);
}
else {
month = stoi(ds, &q);
p = q;//month引用中,参数为int,故q转为int的p
if (month < 1 || month >12)
throw invalid_argument("月份错误");
if (ds[p++] != '/')
throw invalid_argument("间隔符出错");
day = get_day(ds, month, p);
if (ds[p++] != '/')
throw invalid_argument("间隔符出错");
year = get_year(ds, p);
//month = ds.find_first_of("0123456789")
}
}
//给cout << date;的构造函数
ostream & operator<<(ostream& out, const date& d)
{
out << d.y() << "年" << d.m() << "月" << d.d() << "日" << endl;
return out;
}
#endif
main函数内容 为:
//--------------------------Main函数--------------------------------------------------------
#include<iostream>
#include<string>
#include<stdexcept>
#include<vector>
#include"date.h"
using namespace std;
int main()
{
string dates[] = {"Jan 1 2014",
"Feb 1 2014",
"February 1 2014",
"3/1/2014"
"3 1 2014",
};
try {
for (auto ds : dates) {
date d1(ds);
cout << d1;
}
}
catch (invalid_argument e) {
cout << e.what() << endl;
}
return 0;
}