`
kennethf6986
  • 浏览: 68350 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

10.11.2 IO之读取结构化的值

阅读更多
利用标准输入循环来解决一个实际问题
假定要处理一个温度读数文件,其结构为:
{year 1990}
{year 1991{month jun }}
{year 1992{month jan (1 0 61.5)} {month feb (1 1 64) (2 2 65.2)}}
{year 2000
   {month feb (1 1 68)(2 3 66.66)(1 0 67.2) }
   {month dec (15 15 -9.2)(15 14 -8.8) (14 0 -2)}
}

const int not_a_reading = -7777;
const int not_a_month = -1;

const int implausible_min = -200;
const int implausible_max = 200;


struct Day{
	vector<double> hour;
	Day();
};

Day::Day() :hour(24)
{
	for(int i=0; i<hour.size();++i) hour[i] = not_a_reading;
}

struct Month{
	int month;
	vector<Day> day;
	Month():month(not_a_month),day(32)
	{

	}
};

struct Year{
	int year;
	vector<Month> month;
	Year():month(12){}
};


struct Reading{
	int day;
	int hour;
	double temperature;
};

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 < implausible_min || implausible_max < r.temperature)
		return false;

	return true;
}

void end_of_loop(istream& ist, char term, const string& message )
{
	if(ist.fail()) {
		ist.clear();
		char ch;
		if(ist>>ch && ch==term) return ;
		cout<<"error"<<message;
		error(message);
	}
}

vector<string> month_input_tbl;
vector<string> month_print_tbl;

void init_input_tbl(vector<string>& tbl )
{
	tbl.push_back("jan");
	tbl.push_back("feb");
	tbl.push_back("mar");
	tbl.push_back("apr");
	tbl.push_back("may");
	tbl.push_back("jun");
	tbl.push_back("jul");
	tbl.push_back("aug");
	tbl.push_back("sep");
	tbl.push_back("oct");
	tbl.push_back("nov");
	tbl.push_back("dec");
}

int month_to_int(string s)
{
	for(int i=0; i<12; ++i) 
		if(month_input_tbl[i] == s) return i;
}

void init_print_tbl(vector<string>& tbl )
{
	tbl.push_back("January");
	tbl.push_back("February");
	tbl.push_back("March");
	tbl.push_back("April");
	tbl.push_back("May");
	tbl.push_back("June");
	tbl.push_back("July");
	tbl.push_back("August");
	tbl.push_back("September");
	tbl.push_back("October");
	tbl.push_back("November");
	tbl.push_back("December");	
}

string int_to_month(int i)
{
	if(i<0 || 12<=i)  {
		cout<<"error"<<	"bad month index"<<i<<endl;
		error("bad month index");
	}
	return month_print_tbl[i];
}


ostream& operator<<(ostream& os, const Reading& r )
{
	return os<<'('<<r.day
			 <<' '<<r.hour
			 <<' '<<r.temperature<<')';
}

ostream& operator<<(ostream& os, const Month& m)
{
	Reading r;
	Day d;
	os<<"{month "<<int_to_month(m.month)<<' ';
	for(int i=0; i<m.day.size(); ++i) {
		d =  m.day[i];
		for(int j=0; j<d.hour.size(); ++j) {
			if(d.hour[j]!=not_a_reading) {
				r.day = i;
				r.hour = j;
				r.temperature = d.hour[j];
				os<<r;
			}
		}
	}
	return os<<"}";
}

ostream& operator<<(ostream& os, const Year& y)
{
	os<<"{year "<<y.year;
	for(int i=0; i<y.month.size(); ++i) {
		Month m = y.month[i];
		if(m.month != not_a_month)
		os<<m;
	}
	return os<<"}"<<endl;

}

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!=')') {
		cout<<"error"<<"bad reading";
		error("bad reading");
	}

	r.day = d;
	r.hour = h;
	r.temperature = t;
	return is;
}


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") {
		cout<<"error"<<"bad start of month";
		error("bad start of month");

	}

	m.month = month_to_int(mm);
	

	Reading r;
	int duplicats = 0;
	int invalids = 0;
	while (is >> r)
	{
		if(is_valid(r)) {
			if (m.day[r.day].hour[r.hour] != not_a_reading ){
				cout<<m.month<<r.day<<r.hour<<endl;
				++duplicats;
			}
				
			m.day[r.day].hour[r.hour] = r.temperature;
		}else
			++invalids;
	}
	
	if(invalids) {
		cout<<"invlid readings in month "<<invalids;
		error("invlid readings in month",invalids);
	}
	if(duplicats) {
		cout<<"duplicate readings in month "<<duplicats;
		error("duplicate readings in month", duplicats);
	}
	
	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_marker;
	int yy;
	is>>year_marker>>yy;
	
	if(!is || year_marker != "year"){
		cout<<"bad start if year";
		error("bad start if year");
	} 
	y.year = yy;
	

	Month m;
	while(is>>m) {
		y.month[m.month] = m;
		m = Month();
	}
	
	end_of_loop(is,'}',"bad end of year");
	return is;
}



void main()
{
	init_input_tbl(month_input_tbl);
	init_print_tbl(month_print_tbl);
	cout<<"please enter input file name\n";
	string name;
	cin >> name;
	ifstream ifs(name.c_str());
	if(!ifs) error("can't open input file",name);
	
	ifs.exceptions(ifs.exceptions() | ios_base::badbit);

	//open an out put file
	cout<<"please enter output file name\n";
	cin>>name;
	ofstream ofs(name.c_str());
	if(!ofs) error( "can't open  output file,", name);


	vector<Year> ys;
	while(true)
	{
		Year y;
		if(!(ifs >> y)) break;
		ys.push_back(y);
	}

	cout<<"read "<<ys.size()<<" years of readings\n";

	//自定义输出
	for(int j=0; j < ys.size(); j++)
	{
		ofs<<ys[j];
	}

	keep_window_open();

}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics