#include"../../std_lib_facilities.h"intmain()try{
string iname{"10_1-Integers.txt"};
ifstream ist{ iname };if(!ist)error("can't open input file", iname);int sum{0};for(int x =0; ist >> x;)
sum += x;
cout <<"The sum of integers is "<< sum << endl;return0;}catch(runtime_error& e){
cerr <<"Runtime error: "<< e.what()<< endl;return1;}catch(...){
cerr <<"Exception occured!\n";return2;}
#include"../../std_lib_facilities.h"structReading{//温度数据读取int hour;//在[0:23]区间取值的小时数double temperature;//华氏温度值};inlinedoublectof(double c){//摄氏温度转换为华氏温度return1.8* c +32.0;}intmain()try{
string iname{"raw_temps.txt"};
ifstream ist{ iname };if(!ist)error("can't open input file", iname);
vector<Reading>vr;int hour;double temperature, sum{0}, average{0};char corf{'n'};while(ist >> hour >> temperature >> corf){if(hour <0|| hour >23)error("hour out of range");if(corf =='c')// 如果是摄氏温度
temperature =ctof(temperature);elseif(corf !='f')//如果既不是摄氏温度又不是华氏温度error("It's neither Celsius nor Fahrenheit");
vr.push_back(Reading{ hour, temperature });
sum += temperature;}
size_t sz = vr.size();
average = sum / sz;//温度平均值
vector<double>vt(sz);for(size_t i =0; i < sz; i++)
vt[i]= vr[i].temperature;sort(vt);double mid{0};if(sz %2)
mid = vt[sz /2];else
mid =(vt[sz /2]+ vt[sz /2+1])/2;
cout <<"Average of temperature is "<< average << endl;
cout <<"Middle of temperature is "<< mid << endl;return0;}catch(runtime_error& e){
cerr <<"Runtime error: "<< e.what()<< endl;return1;}catch(...){
cerr <<"Exception occured!\n";return2;}
10.5
voidprint_year(ostream& os, Year& y){
os <<"{ "<< year_marker << y.year <<'\n';for(Month& m : y.month){if(m.month != not_a_month){
os <<'\t';print_month(os, m);
os <<'\n';}}
os <<"}\n";}
/*
calculator07.cpp
It may be called "finished" calculator.
本程序实现了一个简单的表达式计算器,支持变量操作
从cin读入,输出到cout。
输入文法如下:
Calculation:
Statement
Print
Quit
Calculation Statement
Print:
';'
Quit:
'q'
"quit"
Statement:
Declaration
Expression
Declaration:
"let" name '=' Expression
"const" name '=' Expression
Expression:
Term
Expression '+' Term
Expression '-' Term
Term:
Primary
Term * Primary
Term / Primary
Term % Primary
Primary:
Number
'(' Expression ')'
- Primary //处理负数
Assignment
Number:
floating-point-literal
Assignment:
name '=' Expression
*/#include"../../std_lib_facilities.h"#include"Roman_int.h"structToken{char kind;//int value;
Roman_int roman;
string name;Token(char ch):kind(ch),roman(0){}Token(char ch, Roman_int r):kind(ch),roman(r){}Token(char ch, string n):kind(ch),name(n){}};classToken_stream{private:bool full;
Token buffer;public:Token_stream():full(false),buffer(0){}// The constructor just sets full to indicate that the buffer is empty:
Token get();voidputback(Token t);voidignore(char);};const string declkey ="let";constchar let ='L';const string quitkey ="quit";constchar quit ='q';const string helpkey ="help";constchar help ='h';constchar print =';';constchar number ='8';constchar name ='a';constchar assign ='=';constchar con ='C';const string constkey ="const";
Token Token_stream::get(){if(full){
full =false;return buffer;}char ch;//cin >> ch; // note that >> skips whitespace (space, newline, tab, etc.)while(isspace((ch = cin.get()))&& ch !='\n')continue;switch(ch){case'(':case')':case'+':case'-':case'*':case'/':case'%':case'=':case quit:case print:return Token{ ch };// let each character represent itselfcase'\n':return Token{ print };/*case '.':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':*/case'I':case'V':case'X':case'L':case'C':case'D':case'M'://暂不支持小写字母,因为会与let和const冲突{
cin.putback(ch);// put digit back into the input stream//cin.unget(); // same as putback(char), except no parameter
Roman_int r;
cin >> r;// read a floating-point numberreturn Token{ number, r };}default:if(isalpha(ch)){
string s;
s += ch;//名字为字母开头的,带字母数字和下划线的字符串while(cin.get(ch)&&(isalpha(ch)||isdigit(ch)|| ch =='_'))
s += ch;
cin.putback(ch);if(s == declkey)return Token{ let };// 声明变量关键字if(s == constkey)return Token{ con };// 声明常量关键字if(s == helpkey ||(s.size()==1&& s[0]== help))return Token{ help };if(s == quitkey)return Token{ quit };return Token{ name, s };}error("Bad token");}}// The putback() member function puts its argument back into the Token_stream's buffer:voidToken_stream::putback(Token t){if(full)error("putback() into a full buffer.");
buffer = t;
full =true;}voidToken_stream::ignore(char c){if(full && c == buffer.kind){
full =false;return;}
full =false;char ch;while(cin >> ch)if(ch == c)return;}//---------------------------------------------------------// set VariableclassVariable{public:
string name;//double value;
Roman_int roman;bool is_const;Variable(string n, Roman_int r,bool b):name(n),roman(r),is_const(b){}};classSymbol_table{public:Symbol_table(){}
Roman_int get(string var);voidset(string var, Roman_int r);boolis_declared(string var);
Roman_int define(string var, Roman_int r,bool is_const);private:
vector<Variable> var_table;};
Roman_int Symbol_table::get(string s){for(const Variable& v : var_table)if(v.name == s)return v.roman;error("get: undefined name ", s);}voidSymbol_table::set(string s, Roman_int r){for(Variable& v : var_table)if(v.name == s){if(v.is_const)error("set: can not assign to a const ", s);
v.roman = r;return;}error("set: undefined name ", s);}boolSymbol_table::is_declared(string var){//判断var是否已经在var_table中了for(const Variable& v : var_table)if(v.name == var)returntrue;returnfalse;}
Roman_int Symbol_table::define(string var, Roman_int r,bool is_const){//将(var, val)加入var_table中if(is_declared(var))error(var," declared twice");
var_table.push_back(Variable{ var, r, is_const });return r;}
Token_stream ts;
Symbol_table st;//--------Expression---------------
Roman_int expression();
Roman_int assignment(string var){// 函数假设已经读入了赋值语句的左值和赋值符号
Roman_int right =expression();
st.set(var, right);return right;}
Roman_int primary(){
Token t = ts.get();switch(t.kind){case'(':{
Roman_int d =expression();
t = ts.get();if(t.kind !=')')error("'(' expected");return d;}case'-':return-primary();case number:return t.roman;case name:{
Token t2 = ts.get();if(t2.kind != assign){
ts.putback(t2);return st.get(t.name);// if next char is not a assignment operator, then return variable value}elsereturnassignment(t.name);}default:error("primary expected");}}
Roman_int term(){
Roman_int left =primary();while(true){
Token t = ts.get();switch(t.kind){case'*':
left = left *primary();break;case'/':{
Roman_int d =primary();if(d.as_int()==0)error("divide by zero");
left = left / d;break;}case'%':{
Roman_int d =primary();if(d.as_int()==0)error("divide by zero");//left = fmod(left, d);
left = left % d;break;}default:
ts.putback(t);return left;}}}
Roman_int expression(){
Roman_int left =term();while(true){
Token t = ts.get();switch(t.kind){case'+':
left = left +term();break;case'-':
left = left -term();break;default:
ts.putback(t);return left;}}}
Roman_int declaration(char kind){
Token t = ts.get();if(t.kind != name)error("name expected in declaration");
string var_name = t.name;
Token t2 = ts.get();if(t2.kind !='=')error("= missing in declaration of ", var_name);
Roman_int d =expression();bool is_const =(kind == con);
st.define(var_name, d, is_const);return d;}
Roman_int statement(){
Token t = ts.get();switch(t.kind){case let:case con:returndeclaration(t.kind);default:
ts.putback(t);returnexpression();}}voidclean_up_mess(){
ts.ignore(print);}const string prompt ="> ";const string result ="= ";voidhelp_message(){
cout <<"Please enter expressions using floating-point numbers.\n";
cout <<"You can use \"+ - * / %\" operators, ';' to output result, 'h' to help, and 'q' to quit.\n";
cout <<"You can also define variables and constant by using let and const"<< endl;
cout <<"For example: let a = 1 define a variable a, const b = a * 3 define a constant b"<< endl;}voidcalculate(){while(true)try{
cout << prompt;
Token t = ts.get();while(t.kind == print) t = ts.get();// 丢弃之前的所有打印字符if(t.kind == quit)return;if(t.kind == help){help_message();continue;}
ts.putback(t);
cout << result <<statement()<< endl;}catch(runtime_error& e){
cerr << e.what()<< endl;clean_up_mess();}}intmain()try{
cout <<"Welcome to our simple calculator.\n";
cout <<"Please enter expressions using floating-point numbers.\n";
cout <<"You can use \"+ - * / %\" operators, ';' to output result, 'h' to help, and 'q' to quit.\n";
cout <<"You can also define variables and constant by using let and const"<< endl;
cout <<"For example: let a = 1 define a variable a, const b = a * 3 define a constant b"<< endl;calculate();return0;}catch(exception& e){
cerr <<"exception: "<< e.what()<< endl;char c;while(cin >> c && c !=';');return1;}catch(...){
cerr <<"exception\n";char c;while(cin >> c && c !=';');return2;}
/*
calculator07.cpp
It may be called "finished" calculator.
本程序实现了一个简单的表达式计算器,支持变量操作
从is读入,输出到os。
输入文法如下:
Calculation:
Statement
Print
Quit
Calculation Statement
Print:
';'
Quit:
'q'
"quit"
Statement:
Declaration
Expression
Declaration:
"let" name '=' Expression
"const" name '=' Expression
Expression:
Term
Expression '+' Term
Expression '-' Term
Term:
Primary
Term * Primary
Term / Primary
Term % Primary
Primary:
Number
'(' Expression ')'
- Primary //处理负数
Assignment
Number:
floating-point-literal
Assignment:
name '=' Expression
*/#include"../../std_lib_facilities.h"//全局变量输入输出
istream* pis =&cin;
ostream* pos =&cout;#defineis(*pis)#defineos(*pos)structToken{char kind;double value;
string name;Token(char ch):kind(ch),value(0){}Token(char ch,double val):kind(ch),value(val){}Token(char ch, string n):kind(ch),name(n){}};classToken_stream{private:bool full;
Token buffer;public:Token_stream():full(false),buffer(0){}// The constructor just sets full to indicate that the buffer is empty:
Token get();voidputback(Token t);voidignore(char);};const string declkey ="let";constchar let ='L';const string quitkey ="quit";constchar quit ='q';const string helpkey ="help";constchar help ='h';constchar print =';';constchar number ='8';constchar name ='a';constchar assign ='=';const string constkey ="const";constchar con ='C';const string fromkey ="from";constchar from ='F';const string tokey ="to";constchar to ='T';
Token Token_stream::get(){if(full){
full =false;return buffer;}char ch;//is >> ch; // note that >> skips whitespace (space, newline, tab, etc.)while(isspace((ch = is.get()))&& ch !='\n')continue;switch(ch){case'(':case')':case'+':case'-':case'*':case'/':case'%':case'=':case quit:case print:return Token{ ch };// let each character represent itselfcase'\n':return Token{ print };case'.':case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':{
is.putback(ch);// put digit back into the input stream//is.unget(); // same as putback(char), except no parameterdouble val;
is >> val;// read a floating-point numberreturn Token{ number, val };}default:if(isalpha(ch)){
string s;
s += ch;//名字为字母开头的,带字母数字和下划线的字符串while(is.get(ch)&&(isalpha(ch)||isdigit(ch)|| ch =='_'))
s += ch;
is.putback(ch);if(s == declkey)return Token{ let };// 声明变量关键字if(s == constkey)return Token{ con };// 声明常量关键字if(s == fromkey){
string fname;
is >> fname;return Token{ from, fname };// 声明从文件获得输入关键字}if(s == tokey){
string fname;
is >> fname;return Token{ to , fname};// 声明向文件输出关键字}if(s == helpkey ||(s.size()==1&& s[0]== help))return Token{ help };if(s == quitkey)return Token{ quit };return Token{ name, s };}error("Bad token");}}// The putback() member function puts its argument back into the Token_stream's buffer:voidToken_stream::putback(Token t){if(full)error("putback() into a full buffer.");
buffer = t;
full =true;}voidToken_stream::ignore(char c){if(full && c == buffer.kind){
full =false;return;}
full =false;char ch;while(is >> ch)if(ch == c)return;}//---------------------------------------------------------// set VariableclassVariable{public:
string name;double value;bool is_const;Variable(string n,double v,bool b):name(n),value(v),is_const(b){}};classSymbol_table{public:Symbol_table(){}doubleget(string var);voidset(string var,double d);boolis_declared(string var);doubledefine(string var,double val,bool is_const);private:
vector<Variable> var_table;};doubleSymbol_table::get(string s){for(const Variable& v : var_table)if(v.name == s)return v.value;error("get: undefined name ", s);}voidSymbol_table::set(string s,double d){for(Variable& v : var_table)if(v.name == s){if(v.is_const)error("set: can not assign to a const ", s);
v.value = d;return;}error("set: undefined name ", s);}boolSymbol_table::is_declared(string var){//判断var是否已经在var_table中了for(const Variable& v : var_table)if(v.name == var)returntrue;returnfalse;}doubleSymbol_table::define(string var,double val,bool is_const){//将(var, val)加入var_table中if(is_declared(var))error(var," declared twice");
var_table.push_back(Variable{ var, val, is_const });return val;}
Token_stream ts;
Symbol_table st;//--------Expression---------------doubleexpression();doubleassignment(string var){// 函数假设已经读入了赋值语句的左值和赋值符号double right =expression();
st.set(var, right);return right;}doubleprimary(){
Token t = ts.get();switch(t.kind){case'(':{double d =expression();
t = ts.get();if(t.kind !=')')error("'(' expected");return d;}case'-':return-primary();case number:return t.value;case name:{
Token t2 = ts.get();if(t2.kind != assign){
ts.putback(t2);return st.get(t.name);// if next char is not a assignment operator, then return variable value}elsereturnassignment(t.name);}default:error("primary expected");}}doubleterm(){double left =primary();while(true){
Token t = ts.get();switch(t.kind){case'*':
left *=primary();break;case'/':{double d =primary();if(d ==0)error("divide by zero");
left /= d;break;}case'%':{double d =primary();if(d ==0)error("divide by zero");
left =fmod(left, d);break;}default:
ts.putback(t);return left;}}}doubleexpression(){double left =term();while(true){
Token t = ts.get();switch(t.kind){case'+':
left +=term();break;case'-':
left -=term();break;default:
ts.putback(t);return left;}}}doubledeclaration(char kind){
Token t = ts.get();if(t.kind != name)error("name expected in declaration");
string var_name = t.name;
Token t2 = ts.get();if(t2.kind !='=')error("= missing in declaration of ", var_name);double d =expression();bool is_const = kind == con;
st.define(var_name, d, is_const);return d;}doublestatement(){
Token t = ts.get();switch(t.kind){case let:case con:returndeclaration(t.kind);default:
ts.putback(t);returnexpression();}}voidclean_up_mess(){
ts.ignore(print);}const string prompt ="> ";const string result ="= ";voidhelp_message(){
cout <<"Please enter expressions using floating-point numbers.\n";
cout <<"You can use \"+ - * / %\" operators, ';' to output result, 'h' to help, and 'q' to quit.\n";
cout <<"You can also define variables and constant by using let and const"<< endl;
cout <<"For example: let a = 1 define a variable a, const b = a * 3 define a constant b"<< endl;}voidcalculate(){while(true)try{
cout << prompt;
Token t = ts.get();while(t.kind == print) t = ts.get();// 丢弃之前的所有打印字符if(t.kind == quit)return;if(t.kind == help){help_message();continue;}if(t.kind == from){if(t.kind != from)error("Invalid file name");static ifstream ifs{ t.name };if(!ifs)error("can't open file", t.name);
pis =&ifs;continue;}elseif(t.kind == to){if(t.kind != to)error("Invalid file name");static ofstream ofs{ t.name };if(!ofs)error("can't open file", t.name);
pos =&ofs;continue;}
ts.putback(t);
os << result <<statement()<< endl;}catch(runtime_error& e){
os << e.what()<< endl;clean_up_mess();}}intmain()try{
cout <<"Welcome to our simple calculator.\n";
cout <<"Please enter expressions using floating-point numbers.\n";
cout <<"You can use \"+ - * / %\" operators, ';' to output result, 'h' to help, and 'q' to quit.\n";
cout <<"You can also define variables and constant by using let and const"<< endl;
cout <<"For example: let a = 1 define a variable a, const b = a * 3 define a constant b"<< endl;calculate();return0;}catch(exception& e){
cerr <<"exception: "<< e.what()<< endl;char c;while(is >> c && c !=';');return1;}catch(...){
cerr <<"exception\n";char c;while(is >> c && c !=';');return2;}