这次作业的目标是写一个四则运算小程序。
1.要求能够读取txt格式的试题,并算出标准答案,在使用者输入答案后对其输入的答案按照标准答案判分。
2.关于运算方面,要求支持加减乘除和括号,但是不能出现小数,所有结果只能由整数、真分数和假分数表示。
3.其次关于拓展功能,要求能够程序自己生成题目而不是从txt中读取,而且生成的题目不能重复,题目运算种类分布均匀。
在两个学期之前的数据结构课上,我们曾经实现过这种简单的综合运算的计算器。所以我打算用相同的思路,采用栈的结构来存储运算符号和数值,并设计算法组织运算的先后顺序,实现括号→乘除→加减的优先级。
为了实现功能的自定义,我没有采用库中封装好的栈,而是自己实现了一个栈的类。头文件代码如下:
1 template<typename T> 2 class Stack 3 { 4 private: 5 T * head; 6 int maxSize; 7 int currentSize; 8 public: 9 Stack(); 10 Stack(int mSize); 11 ~Stack(); 12 T top(); 13 bool pop(); 14 bool push(T n); 15 bool clear(); 16 bool isEmpty(); 17 };
其次是程序的主体——计算器类。头文件代码如下:
1 #include "Stack.h" 2 #define MAX_LENGTH 128 3 class Calculator 4 { 5 private: 6 double number; 7 char mark; 8 char question[MAX_LENGTH]; 9 Stack<char> cStack = Stack<char>(80); 10 Stack<double> dStack = Stack<double>(80); 11 12 void storeMark(char const mark); 13 bool priorTo(char input,char top); 14 void calculate(char const mark); 15 void showAns(); 16 double getAns(); 17 void reply(); 18 public: 19 Calculator(); 20 ~Calculator(); 21 void run(); 22 void parse(); 23 };
以上各函数只要明确目标,想清运算符的优先级还是比较好写的。下面着重说说自己这次感受最深的一个方面——文件IO。
由于平时用c++的机会不多(不知道Unity为什么支持C#却不支持C++),尤其是文件IO这块用的更是少,所以在这方面走了不少弯路。由于我们的C++是自学课,而且文件IO这块并不是考试重点,所以我的文件IO手段还停留在C语言的阶段。但是一想起来那个时候文件内指针造成的各种问题以及feof多扫描一次这种不愉快的经历,我决定尝试新的方法。上网看了看,觉得ifstream这个货好厉害,能够将文件的读取简化得像iostream里的cin和cout一样,这等高逼格的方法不能不学。
其实用起来也比较简单,主要的优点是有putback()这个bug一样的函数,谁还需要一个字符一个字符的自己退啊,一个函数搞定。下面是我的代码:
1 void Calculator::parse() 2 { 3 ifstream myfile = ifstream("myfile.txt"); 4 ifstream myfile_temp = ifstream("myfile.txt"); 5 if (!myfile){ 6 cout << "Unable to open myfile"; 7 system("pause"); 8 } 9 if (!myfile_temp){ 10 cout << "Unable to open myfile"; 11 system("pause"); 12 } 13 while (!myfile.eof())//EOF在文件尾会多循环一次 14 { 15 myfile >> mark; 16 switch (mark) 17 { 18 case ‘+‘: 19 case ‘-‘: 20 case ‘*‘: 21 case ‘/‘: 22 case ‘(‘: 23 case ‘)‘: 24 storeMark(mark); 25 break; 26 case ‘=‘: 27 storeMark(‘#‘); 28 myfile_temp.getline(question, MAX_LENGTH); 29 cout << question << endl; 30 //////////////////////////////此处添加输入输出////////////////////////////// 31 reply(); 32 //////////////////////////////////////////////////////////////////////////// 33 //showAns(); 34 break; 35 case ‘0‘: 36 case ‘1‘: 37 case ‘2‘: 38 case ‘3‘: 39 case ‘4‘: 40 case ‘5‘: 41 case ‘6‘: 42 case ‘7‘: 43 case ‘8‘: 44 case ‘9‘: 45 myfile.putback(mark); 46 myfile >> number; 47 dStack.push(number); 48 break; 49 default: 50 break; 51 } 52 mark = ‘!‘;//换成不起作用的字符,防止重复分析字符 53 } 54 myfile.close(); 55 myfile_temp.close(); 56 }
最后附上我的程序目前的效果,还没做出分数以及自动出题,不过也会很快做出来的~
时间: 2024-10-11 10:02:26