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.
Related
Could someone please take the time and try to explain how does this code work, don't understand the break part and how the answer at the end is 0.
int a=3, x;
switch(a==5){
case 0: x=0;break;
case 1: x=1;break;
case 3: x=3;break;
case 5: x=5;break;
default: x=7;
}
printf("%d",x);
Without break, execution would continue from each case to the next (fallthrough) and every path would eventually end up at default and assign 7 to x.
Also note that you have a bug: switch(a==5) should be switch(a).
a==5 returns a true or false value (0 or 1). In this example, most of the cases will not be triggered. Change switch(a==5) to switch(a)
This means that in your example, case 0 is triggered, because a==5 results in false (0).
Since a==5 is false, because a is 3, it returns 0.
That's why case 0: is being triggered.
break; causes the code to stop, and without it the code would continue until default:.
I have an input txt file that looks like so:
3 2
ATCGATTGA
GACTATACG
I'm using fstream, and creating it as a string. I'm then able to turn 3 and 2 into their own separate ints, but want to also turn the next two lines into ints as well. I'm trying to use getline() because I am told that would be the most efficient, but can't figure out how to create the lower two as their own ints. Any help on how to get that to work?
getline isn't going to convert a string to an int. Just not what it's intended to do.
If you want to convert ATCGATTGA to an int, the obvious approach would be to treat the input as base 4. If memory serves, the "order" is usually given as A-T-C-G. Assuming that's correct, you'd treat them as A=0, T=1, C=2, G=3, and convert the sequences accordingly (but note that for our purposes, the order you choose doesn't really matter, as long as you use the same order for both encoding and decoding).
int cvt_amino(std::string const &amino) {
int result = 0;
for (char c : amino) {
result *= 4;
switch(c) {
case 'a':
case 'A':
result += 0;
break;
case 't':
case 'T':
result += 1;
break;
case 'c':
case 'C':
result += 2;
break;
case 'g':
case 'G':
result += 3;
break;
default:
throw std::runtime_error("Error: bad argument");
}
}
return result;
}
The result is a unique number for each sequence (up to the maximum that will fit in an int). Modulo bugs (I haven't tested this code) you should be able to convert a result back to the original sequence that generated it.
That does assume that the length of each original sequence is known/fixed. If lengths might vary, you won't know the number of leading 'A's to include. In such a case, you probably want to switch to base 5, and change the mapping to A=1, T=2, C=3, G=4. This removes the ambiguity with respect to variable-length inputs (but reduces the maximum length that will fit in a given variable size).
As far as reading data from the file goes, it seems pretty trivial, at least assuming we know the input format. For the format you've given above, you might use something like this:
int a, b;
your_file >> a >> b; // read the 3 and 2
// We'll assume an arbitrary number of space-separated sequences after that:
std::string input;
std:vector<int> values;
while (your_file >> input)
values.push_back(cvt_amino(input));
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;
}
How can I convert the following if=statement to a switch-statement WITHOUT needing to create a case for every number between that interval (41-49)? Is it possible?
if (num < 50 && num > 40)
{
printf("correct!");
}
You have to enumerate every case for a switch. The compiler converts this to a jump table, so you can't use ranges. You can, however, have multiple cases use the same block of code, which may be closer to what you want.
switch(num) {
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
case 48:
case 49:
printf("correct!");
break;
default:
break;
}
What about this?
switch ((num-41)/9) {
case 0:
printf("correct!");
break;
}
bool criteria1 = (num < 50 && num > 40);
switch criteria1: ...
It may result in multilevel decision networks.. scary?
In C or C++ (since you are using printf, I'll assume that's what it is), cases need to be enumerated for each choice.
The only difference between switch/case and if is the possibility that the compiler can turn it into a computed goto instead of checking ranges. If switch/case supported ranges, that would defeat the purpose of opening the possibility of this optimizaton.
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.