fork(2) download
  1. // Remove comments to use this program. Other similar programs - basic_calculator_tt_6.cpp, calculator02buggy.cpp, calculator00.cpp
  2.  
  3.  
  4. //
  5. // This is example code from Chapter 6.7 "Trying the second version" of
  6. // "Software - Principles and Practice using C++" by Bjarne Stroustrup
  7. //
  8.  
  9. /*
  10. This file is known as calculator02buggy.cpp
  11.  
  12. I have inserted 5 errors that should cause this not to compile
  13. I have inserted 3 logic errors that should cause the program to give wrong results
  14.  
  15. First try to find an remove the bugs without looking in the book.
  16. If that gets tedious, compare the code to that in the book (or posted source code)
  17.  
  18. Happy hunting!
  19.  
  20. */
  21.  
  22. #include "std_lib_facilities.h"
  23.  
  24. //------------------------------------------------------------------------------
  25.  
  26. int fact(int x)
  27. {
  28. int val = 1, i = 0;
  29. while (x > 0){
  30. val *= x;
  31. --x;
  32. }
  33. return val;
  34. }
  35.  
  36. //------------------------------------------------------------------------------
  37.  
  38. class Token {
  39. public:
  40. char kind; // what kind of token
  41. double value; // for numbers: a value
  42. Token(char ch) // make a Token from a char
  43. :kind(ch), value(0) { }
  44. Token(char ch, double val) // make a Token from a char and a double
  45. :kind(ch), value(val) { }
  46. };
  47.  
  48. //------------------------------------------------------------------------------
  49.  
  50. class Token_stream {
  51. public:
  52. Token_stream(); // make a Token_stream that reads from cin
  53. Token get(); // get a Token (get() is defined elsewhere)
  54. void putback(Token t); // put a Token back
  55. private:
  56. bool full; // is there a Token in the buffer?
  57. Token buffer; // here is where we keep a Token put back using putback()
  58. };
  59.  
  60. //------------------------------------------------------------------------------
  61.  
  62. // The constructor just sets full to indicate that the buffer is empty:
  63. Token_stream::Token_stream()
  64. :full(false), buffer(0) // no Token in buffer
  65. {
  66. }
  67.  
  68. //------------------------------------------------------------------------------
  69.  
  70. // The putback() member function puts its argument back into the Token_stream's buffer:
  71. void Token_stream::putback(Token t)
  72. {
  73. if (full) error("putback() into a full buffer");
  74. buffer = t; // copy t to buffer
  75. full = true; // buffer is now full
  76. }
  77.  
  78. //------------------------------------------------------------------------------
  79.  
  80. Token Token_stream::get()
  81. {
  82. if (full) { // do we already have a Token ready?
  83. // remove token from buffer
  84. full = false;
  85. return buffer;
  86. }
  87.  
  88. char ch;
  89. cin >> ch; // note that >> skips whitespace (space, newline, tab, etc.)
  90.  
  91. switch (ch) {
  92. case ';': // for "print"
  93. case 'q': // for "quit"
  94. case '{': case '}': case '(': case ')': case '+': case '-': case '*': case '/': case '%': case '!':
  95. return Token(ch); // let each character represent itself
  96. case '.':
  97. case '0': case '1': case '2': case '3': case '4':
  98. case '5': case '6': case '7': case '8': case '9':
  99. {
  100. cin.putback(ch); // put digit back into the input stream
  101. double val;
  102. cin >> val; // read a floating-point number
  103. return Token('8', val); // let '8' represent "a number"
  104. }
  105. default:
  106. error("Bad token");
  107. }
  108. }
  109.  
  110. //------------------------------------------------------------------------------
  111.  
  112. Token_stream ts; // provides get() and putback()
  113.  
  114. //------------------------------------------------------------------------------
  115.  
  116. double expression(); // declaration so that primary() can call expression()
  117.  
  118. //------------------------------------------------------------------------------
  119.  
  120. // deal with numbers and parentheses
  121. double primary()
  122. {
  123. Token t = ts.get();
  124. switch (t.kind) {
  125. case '{':
  126. {
  127. double d = expression();
  128. t = ts.get();
  129. if (t.kind != '}') error("'}' expected");
  130. return d;
  131. }
  132. case '(': // handle '(' expression ')'
  133. {
  134. double d = expression();
  135. t = ts.get();
  136. if (t.kind != ')') error("')' expected)");
  137. return d;
  138. }
  139. case '8': // we use '8' to represent a number
  140. {
  141. double d = t.value;
  142. t = ts.get();
  143. if (t.kind == '!'){
  144. if (d - (int)d == 0)
  145. return fact((int)d); // return factorial of the number
  146. else
  147. error("integer operand not found for '!' opertion");
  148. }
  149. else{
  150. ts.putback(t);
  151. return d; // return the number's value
  152. }
  153. }
  154. default:
  155. error("primary expected");
  156. }
  157. }
  158.  
  159. //------------------------------------------------------------------------------
  160.  
  161. // deal with *, /, and %(ok)
  162. double term()
  163. {
  164. double left = primary();
  165. Token t = ts.get(); // get the next token from token stream
  166.  
  167. while (true) {
  168. switch (t.kind) {
  169. case '*':
  170. left *= primary();
  171. t = ts.get();
  172. break;
  173. case '/':
  174. {
  175. double d = primary();
  176. if (d == 0) error("divide by zero");
  177. left /= d;
  178. t = ts.get();
  179. break;
  180. }
  181. case '%':
  182. {
  183. double d1 = primary();
  184. if ((left - (int)left > 0) || (d1 - (int)d1 > 0))
  185. error("can't use % operation for doubles");
  186. left = (int)left % (int)d1;
  187. t = ts.get();
  188. break;
  189. }
  190. default:
  191. ts.putback(t); // put t back into the token stream
  192. return left;
  193. }
  194. }
  195. }
  196.  
  197. //------------------------------------------------------------------------------
  198.  
  199. // deal with + and -
  200. double expression()
  201. {
  202. double left = term(); // read and evaluate a Term
  203. Token t = ts.get(); // get the next token from token stream
  204.  
  205. while (true) {
  206. switch (t.kind) {
  207. case '+':
  208. left += term(); // evaluate Term and add
  209. t = ts.get();
  210. break;
  211. case '-':
  212. left -= term(); // evaluate Term and subtract
  213. t = ts.get();
  214. break;
  215. default:
  216. ts.putback(t); // put t back into the token stream
  217. return left; // finally: no more + or -: return the answer
  218. }
  219. }
  220. }
  221.  
  222. //------------------------------------------------------------------------------
  223.  
  224. int main()
  225. {
  226. double val = 0;
  227. try
  228. {
  229. // Welcome message
  230. cout << "Welcome to our simple calculator."
  231. << "\nPlease enter expressions using floating-point numbers.\n\n";
  232. // Instructions to use calculator
  233. cout << " How to use this calculator -\n"
  234. << "\t1. Operations supported: +, -, *, /, % (for integers only).\n"
  235. << "\t2. Use expressions like 1+2/3*4-5, followed by ';' to terminate expression.\n"
  236. << "\t3. Evaluation of multiple expressions is supported.\n"
  237. << "\t4. You can use square brackets or parenthesis or both in expressions as usual, for example, (1-2)*{(3-4)/2}.\n"
  238. << "\t5. Use 'q' to close the application.\n\n";
  239.  
  240. // Simple calculator
  241. while (cin) {
  242. cout << "> ";
  243. Token t = ts.get();
  244.  
  245. if (t.kind == 'q') break; // 'x' for quit
  246. if (t.kind == ';'){ // ';' for "print now"
  247. cout << "=" << val << '\n';
  248. //continue;
  249. }
  250. else
  251. ts.putback(t);
  252. val = expression();
  253. }
  254. keep_window_open();
  255. return 0;
  256. }
  257. catch (exception& e) {
  258. cerr << "error: " << e.what() << '\n';
  259. keep_window_open();
  260. return 1;
  261. }
  262. catch (...) {
  263. cerr << "Oops: unknown exception!\n";
  264. keep_window_open();
  265. return 2;
  266. }
  267. }
  268. //------------------------------------------------------------------------------
  269.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
1+2;
compilation info
prog.cpp:22:32: fatal error: std_lib_facilities.h: No such file or directory
 #include "std_lib_facilities.h"
                                ^
compilation terminated.
stdout
Standard output is empty