I am tasked with writing a code to test whether a number is positive, negative, or zero using switch and "?:". Here's what I have. Negative values don't seem to work and I can't figure out how to implement zero. In fact, I don't really quite understand how the whole case1, case2 and switch syntax and how it works in general.
#include <iostream>
using namespace std;
int main()
{
int a;
int b;
cout << "Please enter the value to be tested: ";
cin >> a;
(a > 0) ? (b = 1) : (b = 2);
switch (b)
{
case 1:
cout << "The given value is positive." << endl;
break;
case 2:
cout << "The given value is negative." << endl;
break;
}
return 0;
}
Switch Statement:
The switch statement provides a convenient alternative to the if when
dealing with a multi-way branch. Suppose we have some integer value
called test and want to do different operations depending on whether
it has the value 1, 5 or any other value, then the switch statement
could be employed
Syntax:
switch(expression resulting to integer literals/integer literals/enumeration types/){
case constant-expression :
statement(s);
break; //optional
case constant-expression :
statement(s);
break; //optional
// you can have any number of case statements.
default : //Optional and one default statement can be present for a switch
statement(s);
}
The following rules apply to a switch statement:
The expression used in a switch statement must have an integral or
enumerated type, or be of a class type in which the class has a
single conversion function to an integral or enumerated type.
You can have any number of case statements within a switch. Each case
is followed by the value to be compared to and a colon.
The constant-expression for a case must be the same data type as the
variable in the switch, and it must be a constant or a literal.
When the variable being switched on is equal to a case, the
statements following that case will execute until a break statement
is reached.
When a break statement is reached, the switch terminates, and the
flow of control jumps to the next line following the switch
statement.
Not every case needs to contain a break. If no break appears, the
flow of control will fall through to subsequent cases until a break
is reached.
A switch statement can have an optional default case, which must
appear at the end of the switch. The default case can be used for
performing a task when none of the cases is true. No break is needed
in the default case.
It works as follows:-
The expression, just test in this case, is evaluated.
The case labels are checked in turn for the one that matches the
value.
If none matches, and the optional default label exists, it is
selected, otherwise control passes from the switch compound statement
If a matching label is found, execution proceeds from there. Control
then passes down through all remaining labels within the switch
statement. As this is normally not what is wanted, the break
statement is normally added before the next case label to transfer
control out of the switch statement.
One useful exception occurs when you want to do the same
processing for two or more values. Suppose you want values 1 and
10 to do the same thing, then:-
case 1 :
/*.
any number of cases
.
*/
case 10:
// Process below statements for case 1 to 10
break;
works because the test = 1 case just "drops through" to the next section.
Conditional Operator:
The ternary operator (?:) is a very useful conditional expression used in C and C++. It's effects are similar to the if statement but with some major advantages.
The basic syntax of using the ternary operator is thus:
(condition) ? (if_true) : (if_false)
Which is basically the same as:
if (condition)
if_true;
else
if_false;
Therefore if "condition" is true, the second expression is executed ("if_true"), if not, the third is executed ("if_false").
For you Code:
You can use any of the way to find, one way is,
#define POSITIVE (1)
#define NEGATIVE (-(1))
#define ZERO (0)
switch ( ( user_input >= ZERO )? POSITIVE : NEGATIVE )
{
case POSITIVE:
if( user_input == ZERO )
{
cout << "The given value is a Zero." << endl;
}
else
{
cout << "The given value is positive." << endl;
}
break;
case NEGATIVE:
cout << "The given value is negative." << endl;
break;
}
Related
I want to apply if statement to check a condition with multiple values, which I know should be something like this:
if (value == 1 || value == 2 || value == 3 || value == 4)
//Do something;
But this does not look good, isn't there any way to check like:
if(value == 1 || 2 || 3 || 4)
Note: I am not trying something in range like:
if (1 <= value && value <= 4)
No you can not write it as :
if(value==1 || 2 || 3 || 4)
You can use conditional statement for different conditions.
A possible simple alternative would be:
switch (value) { case 1: case 2: case 3: case 4: std::cout << "true"; }
Live sample
Wether it looks better or not is a matter of taste.
Another alternative would be:
switch (value) { case 1 ... 4: std::cout << "true"; }
Live sample
But this is not standard C++, I believe it's a GNU extension.
In case the range of possible values is smaller than the number of bits you can do something like this:
int value = 2;
auto values = {1,2,3,4};
int test = 0;
for(auto i : values)
test |= (1 << i);
if((1 << value) & test)
std::cout << "true" << std::endl;
If you have direct control over the possible values you can also directly set them as bitflags and skip the bitshift part.
Otherwise there is also the option of inverting the condition in case there are fewer possible values that should evaluate to false.
Also you could just loop over an array of valid values and see if any of them matches.
No you cannot write the way you have described. You still have option of switch case and ternary operators.
If you want to make it fancy you still have option like
vector<int> v = {1,2,3,4,5}; // desirable values
auto it = find(v.begin(), v.end(), value);
if(it != v.end()){
cout<<"value is equal to something!\n";
// if you want to check which value does it match to
cout<<"Matching value is at index "<<it-v.begin()<<"\n";
}else {
cout<<"Value is not equal to any number!\n";
}
For this you will need to include vector library by using #include <vector>
Well, I had the same issue and this is the solution I came up.
I created an array, with the values I want to check, and then I use the native array includes() method to check if the variable value exists on the array. Like this:
[1, 2, 3, 4].includes(value);
If the variable value exists on the array the includes() method will return a boolean with the value true. Otherwise it will return a boolean with the value false.
so this is the code that im trying to get to work but it displays "duplicate case value" whenever it reaches for B
im a first year college student so i might have used a wrong format or i might be overlooking something i really dont seem to figure out the problem so i turn to you guys for help
char dep;
int exp;
cout<<"please enter your department, A, B OR C: ";
cin>>dep;
cout<<"please enter your years of experience ";
cin>>exp;
switch(dep)
{
case 'A' || 'a' :{
switch (exp) {
case 5:
cout<<"you will recieve a 5% raise and 2.5% extra due to your experience";
break;
defualt : cout<<"you get 5% raise";
break;
}
}
break;
case 'B' || 'b' :{
switch (exp) {
case 5:
cout<<"you will recieve a 2% raise and 2.5% extra due to your experience";
break;
defualt : cout<<"you get 2% raise";
break;
}
}
break;
Though it compiles (or would without the B version), and spells what you wanted if roughly translated to English, case 'A' || 'a' does not do what you think it does.
The expression after case is treated as an exact match for the selection statement — it's compared exactly to dep. You can't throw in a more complex expression and expect it to be "unrolled" into multiple comparisons. Think of switch/case as a simple lookup table, rather than an intelligent branching feature (that's what if is for!).
Perhaps confusingly, the expression 'A' || 'a' is valid in its own right, but (like any expression) it evaluates to a single value: either true or false, depending on whether either of the operands if "truthy". In this particular example, neither has ASCII value zero so both is truthy, and the expression is always true. It'll be converted to the type of dep (the rules say it becomes 1) and used for that exact lookup.
Since you did this with 'B' and 'b' too, you do then indeed have two equivalent cases.
Instead, write a separate case for each condition. Fortunately, since cases fall through, you don't need to repeat the "body" of the case: you can just put the two cases next to each other; just don't put a break between them:
case 'A':
case 'a':
// code here
break;
case 'B':
case 'b':
// code here
By the way, you misspelt default.
I seem to be running into an issue. While trying to get input based off of A.M./P.M. entry,my if else statement is having some sort of logic error. I've never really done this sort of thing (I'm a bit new to c++) so help would be appreciated.
cout << "What time was the dose administered? (Round to hour): ";
cin >> time;
cout << "A.M./P.M.? ";
cin >> ap;
cout << ap;
if (ap == "A.M.", "am"){
ap = "A.M.";
}
else if (ap == "P.M.", "pm"){
ap = "P.M.";
}
else { cout << "This is not a valid entry.";
}
"ap" is a string.
No matter what is entered, the result is "A.M."
Side note: Originally, it would only print "P.M." but both statements were orignally "if", when I changed it to "if else" it began printing "A.M." only.
This...
ap == "A.M.", "am"
...under the rules of operator precedence, is equivalent to...
"am"
...which in a boolean context undergoes standard conversion to true (via a non-0 pointer).
That's because the comma operator evaluates the sub-expression on its left - namely ap == "A.M." - and while any side-effects of that evaluation are enacted the actual value of the sub-expression is then discarded and the sub-expression on the right - namely "am" - is evaluated and used instead.
You should instead use:
if (ap == "A.M." || ap == "am")
(The C++ Standard allows the keyword "or" as an alternative to ||, but famously Microsoft's compiler doesn't support it without an extra command-line argument, so in practice it's best avoided for portable code.)
This question already has answers here:
Does case-switch work like this?
(5 answers)
Closed 8 years ago.
Given the following sequence
switch(1) {
case 1:
cout << "first \n";
case 2:
cout << "second \n";
default:
cout << "Not first nor the second";
}
the output is
first
second
Not first nor the second
I'm expecting the output to be
first
so, how do values are compared? I know I didn't use the break statement, but isn't that just to save cpu time? How come the second case executes since there are two different integer values? What am I missing?
I'm using gcc 4.9.2 with -std=c++11 flag.
If you don't use break the code just continues. I guess it's a bit like a GOTO label in that sense. There are legitimate uses for omitting the break statement, such as when you want to do an or ...
switch(val) {
case 1:
case 2:
// if val is 1 or 2...
break;
case 3:
// if val == 3;
break;
}
I am writing a C++ program that prompts the user for an input and then keeps track of how many times that input is entered. I am currently using a do-while loop and a switch statement. The part I am having trouble with is the switch statement. I can't figure out how to keep track of how many times an input is entered. For example:
Enter Value: 4
Enter Value: 4
Enter Value: 4
Enter Value: 3
Enter Value: 3
// I then want the program to be able to know and then eventually output, how many times the number '4' and '3' were entered.
I thinking possibly using some sort of increment counting form, but not 100% sure.
Thanks!
You'll probably want to use a std::map<int,int>. Here's why.
Let's look at alternatives, starting with the obvious:
int count0;
int count1;
int count2;
int count3;
int count4;
...
switch(input) {
case 0: ++count0; break;
case 1: ++count1; break;
case 2: ++count2; break;
case 3: ++count3; break
case 4: ++count4; break;
}
This does what you ask: you evaluate the input, and keep track of the number of times that specific input has been seen. This form does suffer from many problems:
It requires one line of source code for each alternative. This becomes a problem when the user can enter any value, say, from 0 to 10,000!
It has duplicate, virtually identical lines.
It has many variables, each of which has to be entered independently, but uses identically.
We can reduce the variable count by specifing an array:
int count[5];
...
switch(input) {
case 0: ++count[0]; break;
case 1: ++count[1]; break;
case 2: ++count[2]; break;
case 3: ++count[3]; break;
case 4: ++count[4]; break;
}
This still suffers from too many almost-but-not-quite identical lines of code. Let's try to get rid of the switch statement:
int count[5];
...
++count[input];
Ah, now we are getting somewhere! By eliminating the switch statement, we have one easily-maintained line of code. But what if the user (accidentally or maliciously) enters a 6? Then we will increment count[6], which does not exist. This is a Bad Thing. We could increase the size of the array:
int count[50000];
...
++count[input];
Now we are safe from the user. If he enters a 6, the Bad Thing no longer happens. Uh-oh, what about if the user enters 51000? We will increment count[51000] which does not exist. It should be obvious that we can't win this game -- for any number we choose, the user might choose that number plus 1.
Even if we could win, we'd still lose. If we are only asking the user to enter a few numbers, then we will have wasted the other 49,997 entries in the arary.
Fortunately C++ has a data structure that we can use which:
can take arbitrary numbers as its range, and
is space-efficient (compared to a large wasted array).
That data structure is called a map:
std::map<int,int> count;
...
++count[input];
A map is sort of like an array, but grows itself in a special way. Only the entries that we use are ever allocated, and every entry that we use is automatically allocated.
std::map<int, int> frequency;
int value_entered_by_user = f();
frequency[value_entered_by_user]++;
If your range of input values is limited, you can use an array. Each element of the array represents an input value. Initialize the elements to 0 at the beginning and increment the appropriate element when its corresponding input value is entered.