Advertisement
Guest User

Untitled

a guest
Nov 18th, 2019
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.82 KB | None | 0 0
  1. #include "calculations.hh"
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <sstream> // for implementing function string_to_double
  5. #include <string>
  6. #include <vector>
  7.  
  8. using namespace std;
  9.  
  10. const string GREETING_AT_END = "Thanks and see you later!";
  11.  
  12. // Utility function to sections a string at delimiters
  13. vector< string > split(const string& s,
  14. const char delimiter,
  15. bool ignore_empty = false);
  16.  
  17. // Function string_to_double changes a string comprising a real number
  18. // into a float type value for calculations.
  19. // It returns true, if parameter s comprised a real.
  20. // It returns false, if s was not a valid real number.
  21. // The converted float will be assigned into reference parameter result.
  22. // The implementation of the function uses stringstream for the sake of example.
  23. bool string_to_double(const string& s, double& result);
  24.  
  25.  
  26. // TODO: Explore the following data structures!
  27. struct Command {
  28. string str;
  29. vector<string>::size_type parameter_number;
  30. bool exit;
  31. double(*action)(double, double);
  32. };
  33.  
  34. const vector<Command> COMMANDS = {
  35. {"+", 2, false, addition},
  36. {"-", 2, false, subtraction},
  37. {"*", 2, false, multiplication},
  38. {"/", 2, false, division},
  39. {"PLUS", 2, false, addition},
  40. {"MINUS", 2, false, subtraction},
  41. {"TIMES", 2, false, multiplication},
  42. {"DIVIDED", 2, false, division},
  43. {"ADDITION", 2, false, addition},
  44. {"SUBTRACTION", 2, false, subtraction},
  45. {"MULTIPLICATION", 2, false, multiplication},
  46. {"DIVISION", 2, false, division},
  47. {"SUM", 2, false, addition},
  48. {"DIFFERENCE", 2, false, subtraction},
  49. {"PRODUCT", 2, false, multiplication},
  50. {"QUOTIENT", 2, false, division},
  51. {"ADD", 2, false, addition},
  52. {"INCREASE", 2, false, addition},
  53. {"SUBTRACT", 2, false, subtraction},
  54. {"DECREASE", 2, false, subtraction},
  55. {"MULTIPLY", 2, false, multiplication},
  56. {"DIVIDE", 2, false, division},
  57. {"STOP", 0, true, nullptr},
  58. {"QUIT", 0, true, nullptr},
  59. {"EXIT", 0, true, nullptr},
  60. {"Q", 0, true, nullptr},
  61. {"^", 2, false, exponentiation},
  62. {"POWER", 2, false, exponentiation},
  63. {"EXP", 2, false, exponentiation}
  64. };
  65.  
  66. bool check_command (string com) {
  67. for (auto i : COMMANDS) {
  68. if (com == i.str) {
  69. return true;
  70. }
  71. }
  72. return false;
  73. }
  74.  
  75. bool check_parameters (long unsigned e, string command){
  76. for(auto i : COMMANDS){
  77. if (e == i.parameter_number && command == i.str)
  78. return true;
  79. }
  80. return false;
  81. }
  82.  
  83. bool exit (string com) {
  84. for (auto i : COMMANDS) {
  85. if (com == i.str) {
  86. return i.exit;
  87. }
  88. }
  89. return true;
  90. }
  91.  
  92. void print (string com, double left, double right) {
  93. for (auto i : COMMANDS) {
  94. if (com == i.str) {
  95. cout << i.action( left, right ) << endl;
  96. return;
  97. }
  98. }
  99. }
  100.  
  101.  
  102. int main() {
  103.  
  104. // Using precision of two decimals in printing
  105. cout.precision(2);
  106. cout << fixed;
  107.  
  108. while ( true ) {
  109. cout << "calculator> ";
  110.  
  111. string line = "";
  112. getline(cin, line);
  113.  
  114. if ( line.empty() ) {
  115. // By inputting an empty line, the user can make the program end.
  116. cout << GREETING_AT_END << endl;
  117. break;
  118. }
  119.  
  120. vector<string> pieces = split(line, ' ', true);
  121.  
  122. if(pieces.size() == 0){
  123. continue;
  124. }
  125.  
  126. string command_to_be_executed = pieces.at(0);
  127.  
  128. // TODO: Implement command execution here!
  129.  
  130. for (char& c: command_to_be_executed) c = toupper(c);
  131.  
  132. if (!( check_command( command_to_be_executed ))) {
  133. cout << "Error: unknown command." << endl;
  134. }
  135. else {
  136. if ( ! ( check_parameters( pieces.size()-1, command_to_be_executed ) )) {
  137. cout << "Error: wrong number of parameters." << endl;
  138. }
  139. else {
  140. double a;
  141. if ( exit(command_to_be_executed) ) {
  142. cout << GREETING_AT_END << endl;
  143. return false;
  144. }
  145. else if ( ! ( string_to_double(pieces.at(1), a )) or
  146. ( ! ( string_to_double(pieces.at(2), a ))) ) {
  147. cout << "Error: a non-number operand." << endl;
  148. }
  149.  
  150. else {
  151. double l = stod(pieces.at(1));
  152. double r = stod(pieces.at(2));
  153.  
  154. print ( command_to_be_executed, l, r );
  155. }
  156. }
  157. }
  158. }
  159. }
  160.  
  161.  
  162. // This function exemplifies istringstreams.
  163. // It would be possible to use function stod of string to convert a string to
  164. // a double, but to recognize all error cases would be more complicated with it
  165. // at this phase of education.
  166. // It is easier to use the boolean type return value that can be
  167. // examined at calling point as done in the implementation below.
  168. bool string_to_double(const string& s, double& result) {
  169. // Initializing input stream of istringstream type the string that will
  170. // scanned with ">>" or getline.
  171. istringstream stream(s);
  172.  
  173. double tmp;
  174.  
  175. // Reading input value in a normal way with ">>" operator.
  176. // You can operate istringstreams with the same operations as cin
  177. // and other ifstreams.
  178. stream >> tmp;
  179.  
  180. if ( not stream ) {
  181. return false;
  182. }
  183.  
  184. // ws is special operator that skips all the word delimiters (such as spaces)
  185. // until it meets something else
  186. stream >> ws;
  187.  
  188. // If parameter s is a string comprising a valid real number, it cannot
  189. // succeed other characters than spaces.
  190. // Since previous ">> ws" operation threw the spaces away, at this point
  191. // the input stream should contain nothing.
  192. // If it does, then it is erroneous.
  193. // Let's try to read a character from the input stream.
  194. // If this fails, because the input stream has no characters left,
  195. // then all is right.
  196. // If it succeeds, then string s has something that it should not have.
  197. stream.get();
  198.  
  199. if ( stream ) {
  200. return false;
  201. } else {
  202. result = tmp;
  203. return true;
  204. }
  205. }
  206.  
  207. // Model implementation of good old split function
  208. vector< string > split(const string& s,
  209. const char delimiter,
  210. bool ignore_empty){
  211. vector<string> result;
  212. string tmp = s;
  213.  
  214. while(tmp.find(delimiter) != string::npos)
  215. {
  216. string word = tmp.substr(0, tmp.find(delimiter));
  217. tmp = tmp.substr(tmp.find(delimiter)+1, tmp.size());
  218. if(not (ignore_empty and word.empty()))
  219. {
  220. result.push_back(word);
  221. }
  222.  
  223. }
  224. if(not (ignore_empty and tmp.empty()))
  225. {
  226. result.push_back(tmp);
  227. }
  228. return result;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement