1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
#include "std_lib_facilities.h"
using namespace std;
const int not_a_reading=-200;
const int not_a_month=-1;
struct Day
{
vector<double> hour{vector<double>(24, not_a_reading)};
};
struct Month
{
int month {not_a_month};
vector<Day> day{32}; // range 1 to 31 has 32 elements!
};
struct Year
{
int year;
vector<Month> month{12}; //January is 0
};
struct Reading
{
int day;
int hour;
double temperature;
};
vector<string> month_input_tbl={"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};
int month_to_int(string s)
{
for(int i=0; i<12; ++i) if(month_input_tbl[i]==s) return i;
return -1;
}
vector<string> month_print_tbl={"Jan", "Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dic"};
string int_to_month(int i)
{
if(i<0||i>12)error("bad month number");
return month_print_tbl[i];
}
istream& operator>>(istream& is, Reading& r)
{
char ch1;
if(is>>ch1 &&ch1 != '(')
{
is.unget();
is.clear(ios_base::failbit);
return is;
}
char ch2;
int d;
int h;
double t;
is>>d>>h>>t>>ch2;
if(!is||ch2!=')')error("bad reading");
r.day=d;
r.hour=h;
r.temperature=t;
return is;
}
//is.exceptions(is.exeptions()|ios_base::badbit);
void end_of_loop(istream& ist, char term, const string& message)
{
if(ist.fail())
{
ist.clear();
char ch;
if(ist>>ch && ch==term) return;
error(message);
}
}
constexpr int implausibile_min=-200;
constexpr int implausibile_max=200;
bool is_valid(const Reading& r)
{
if(r.day<1||r.day>31)return false;
if(r.hour<0||r.hour>23)return false;
if(r.temperature<implausibile_min||r.temperature>implausibile_max)return false;
return true;
}
istream& operator>>(istream& is, Month& m)
{
char ch=0;
if(is>>ch && ch !='{')
{
is.unget();
is.clear(ios_base::failbit);
return is;
}
string month_marker;
string mm;
is>>month_marker>>mm;
if(!is||month_marker!="month")error("bad start of month");
m.month=month_to_int(mm);
int duplicates=0;
int invalids=0;
for(Reading r; is>>r;)
{
if(is_valid(r))
{
if(m.day[r.day].hour[r.hour]!=not_a_reading)
++duplicates;
m.day[r.day].hour[r.hour]=r.temperature;
}
else
++invalids;
}
if(invalids)error("invalid readings in month",invalids);
if(duplicates)error("duplicates reading in month",duplicates);
end_of_loop(is,'}',"bad end of month");
return is;
}
istream& operator>>(istream&is, Year& y)
{
char ch;
is>>ch;
if(ch!='{')
{
is.unget();
is.clear(ios::failbit);
return is;
}
string year_maker;
int yy;
is>>year_maker>>yy;
if(!is||year_maker!="year")error("bad start of year");
y.year=yy;
while(true)
{
Month m;
if(!(is>>m))break;
y.month[m.month]=m;
}
end_of_loop(is,'}',"bad end of year");
return is;
}
ostream& operator<<(ostream&os, Year& y)
{
/**< return os<<'{'<< y.year
<<','<< int_to_month(month_to_int(y.month[0]))
<<; */
}
int main()
{
cout << "Please enter input file name" << endl;
string iname;
cin>>iname;
ifstream ist {iname};
if(!ist)error("can't open file ", iname);
ist.exceptions(ist.exceptions()|ios_base::badbit);
cout<<"Please enter output file name" << endl;
string oname;
cin>>oname;
ofstream ost{oname};
if(!ost)error("can't open output file ",oname);
vector<Year> ys;
while(true)
{
Year y;
if(!(ist>>y)) break;
ys.push_back(y);
}
cout<<"read "<<ys.size()<< " years of readings\n";
for (Year& y : ys) print_year(ost,y)
return 0;
}
|