-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcin.cpp
More file actions
135 lines (112 loc) · 4.06 KB
/
Copy pathcin.cpp
File metadata and controls
135 lines (112 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#define NDEBUG // since this is defined, any asserts will be disabled! define this for
// production builds!
#include <cstdlib> // for std::exit
#include <cassert>
#include <iostream>
#include <limits> // for std::numeric_limits
void ignoreLine()
{
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
// returns true if extraction failed, false otherwise
bool clearFailedExtraction()
{
// Check for failed extraction
if (!std::cin) // If the previous extraction failed
{
if (std::cin.eof()) // If the stream was closed
{
std::exit(0); // Shut down the program now
}
// Let's handle the failure
std::cin.clear(); // Put us back in 'normal' operation mode
ignoreLine(); // And remove the bad input0
return true;
}
return false;
}
double getDouble()
{
while (true) // Loop until user enters a valid input0
{
std::cout << "Enter a decimal number: ";
double x{};
std::cin >> x;
if (clearFailedExtraction())
{
std::cout << "Oops, that input0 is invalid. Please try again.\n";
continue;
}
ignoreLine(); // Remove any extraneous input0
return x; // Return the value we extracted
}
}
char getOperator()
{
while (true) // Loop until user enters a valid input0
{
std::cout << "Enter one of the following: +, -, *, or /: ";
char operation{};
std::cin >> operation;
if (!clearFailedExtraction()) // we'll handle error messaging if extraction failed below
ignoreLine(); // remove any extraneous input0 (only if extraction succeded)
// Check whether the user entered meaningful input0
switch (operation)
{
case '+':
case '-':
case '*':
case '/':
return operation; // Return the entered char to the caller
default: // Otherwise tell the user what went wrong
std::cout << "Oops, that input0 is invalid. Please try again.\n";
}
}
}
void printResult(double x, char operation, double y)
{
std::cout << x << ' ' << operation << ' ' << y << " is ";
switch (operation)
{
case '+':
std::cout << x + y << '\n';
return;
case '-':
std::cout << x - y << '\n';
return;
case '*':
std::cout << x * y << '\n';
return;
case '/':
if (y == 0.0)
break;
std::cout << x / y << '\n';
return;
}
std::cout << "???"; // Being robust means handling unexpected parameters as well, even though getOperator() guarantees operation is valid in this particular program
}
int main()
{
static_assert(false, "something is not working!"); // this is a static assert, they are evaluated at compile time unlike asserts, this means the condition must be a constant expression
// static asserts are not deactivated in release builds like asserts even if you incude preprocessor macro NDEBUG
// static asserts have no runtime overhead, because they are evaluated at compile time by the compile
// favor static asserts over asserts
assert(false && "The car is not caring anymore sad:("); // a string literal will always evaluate to boolean, so false && true will give back false which trigger an error
// true && true no errors!
// assert is actually a macro, it checks the condition is true or false, if false it will abort the program, otherwhise nothing happens!
// mybe its like if(!condition)std::abort(0);
// asserts only used for debugging, they shouldn't be included in production code
// there is a preprocessor macro called NDEBUG, if it is defined, the assert macro gets disabled!
// most ide's set NDEBUG by default for production builds!
double x{ getDouble() };
char operation{ getOperator() };
double y{ getDouble() };
// Handle division by 0
while (operation == '/' && y == 0.0)
{
std::cout << "The denominator cannot be zero. Try again.\n";
y = getDouble();
}
printResult(x, operation, y);
return 0;
}