case expression in c++ returns error - c++

I was using this code as part of a 2 dimensional game, but when i tried compiling it, it returned the following error:
error C2051: case expression not constant.
This is my code:
switch(_getch()){
case "w":
dir = UP;
break;
case "a":
dir = LEFT;
break;
case "s":
dir = DOWN;
break;
case "d":
dir = RIGHT;
break;
default:
break;
}

You should use character literals ('w') instead of string literals ("w") in switch cases:
case 'w':
dir = UP;
break;
"w" is a string literal, which would decay to a char const* pointer. switch cases cannot be anything other than a constant integer, an enum or a class with a single non-explicit integer or enum conversion operator. A pointer to char is none of those.

Related

How to do a if condition in a switch statement in c++

I have this code:
#include <iostream>
using namespace std;
int main() {
int square; char state;
cout<<"Write a numbber"; cin>>square;
square *= square;
cout<<square;
switch(square) {
case 1: state = 'h';
case 3: state = 'm';
case 7: state = 'j';
case (square > 10): state = 'u'; // I try this, but not works
}
return 0;
}
I would like to know how a condition is made inside a switch, in c ++.
The expression following case must be a compile time constant. Hence, you may not use what you are trying.
Change that to default: and then use if.
default:
if (square > 10)
state = 'u';
If you have lots of items you should use a switch. If not, if else is better.
If a switch contains more than five items, it's implemented using a lookup table or a hash list. This means that all items get the same access time, compared to a list of if:s where the last item takes much more time to reach as it has to evaluate every previous condition first.
If you want to use condition or combine some:
switch(square) {
case 1: state = 'h'; break;
case 3: state = 'm';break;
case 7: state = 'j'; break;
case 8:
case 9: state = 'u';
case 10: state = 'z';break;
default: state = 'd';
}
Case 8, 9, 10 will be combined if the square is 8.
If you don't have a break at the end of a case region, control passes along to the next case label.

Case Label Does Not reduce to integer constant

I'm not understanding why my switch statement is not working.
I've chopped it up since it was rather long, but the user is supposed to input a character to "selection1' & "selection2" and then I pass those as a parameter to my validSelection() function. The validSelection function is supposed to test the characters for the valid entries and deny all others by returning a boolean.
bool validSelection(char selection)
{
switch (selection)
{
case "R":
case "r":
case "P":
case "p":
case "S":
case "s":
return true;
default:
return false;
}
}
cin >> selection1;
cin >> selection2;
if (validSelection(selection1) && validSelection(selection2))
selection1 and selection2 both are char data types.
As #CaptainObvlious has already pointed out, anything between double-quotes "" is considered as string. However, you ant to pass the integer value to the switch. For the same, you have to put the characters inside single-quotes ''.
You may need to change our code as below.
bool validSelection(char selection)
{
switch (selection)
{
case 'R':
case 'r':
case 'P':
case 'p':
case 'S':
case 's':
return true;
default:
return false;
}
}

Expected unqualified-id

Im doing a random password generator but I have a problem at a switch.
From case 4 to case 18 it says there is an "Expected unqualified-id" and points the '=' sign but I can't get the error.
Is there a problem with the syntaxis or code?
My code:
switch (a) {
case 0:
char[1] = 'a';
break;
case 1:
char[1] = 'b';
break;
case 2:
char[1] = 'c';
break;
case 3:
char[1] = 'd';
break;
case 4:
char[1] = 'e';
break;
Problem: You can not name your array char, because this is a reserved word in C++.
Solution: Rename your array and try again.

Switch statement using or

I'm creating a console app and using a switch statement to create a simple menu system. User input is in the form of a single character that displays on-screen as a capital letter. However, I do want the program to accept both lower- and upper-case characters.
I understand that switch statements are used to compare against constants, but is it possible to do something like the following?
switch(menuChoice) {
case ('q' || 'Q'):
//Some code
break;
case ('s' || 'S'):
//More code
break;
default:
break;
}
If this isn't possible, is there a workaround? I really don't want to repeat code.
This way:
switch(menuChoice) {
case 'q':
case 'Q':
//Some code
break;
case 's':
case 'S':
//More code
break;
default:
}
More on that topic:
http://en.wikipedia.org/wiki/Switch_statement#C.2C_C.2B.2B.2C_Java.2C_PHP.2C_ActionScript.2C_JavaScript
The generally accepted syntax for this is:
switch(menuChoice) {
case 'q':
case 'Q':
//Some code
break;
case 's':
case 'S':
//More code
break;
default:
break;
}
i.e.: Due the lack of a break, program execution cascades into the next block. This is often referred to as "fall through".
That said, you could of course simply normalise the case of the 'menuChoice' variable in this instance via toupper/tolower.
'q' || 'Q' results in bool type result (true) which is promoted to integral type used in switch condition (char) - giving the value 1. If compiler allowed same value (1) to be used in multiple labels, during execution of switch statement menuChoice would be compared to value of 1 in each case. If menuChoice had value 1 then code under the first case label would have been executed.
Therefore suggested answers here use character constant (which is of type char) as integral value in each case label.
Just use tolower(), here's my man:
SYNOPSIS
#include ctype.h
int toupper(int c);
int tolower(int c);
DESCRIPTION
toupper() converts the letter c to upper case, if possible.
tolower() converts the letter c to lower case, if possible.
If c is not an unsigned char value, or EOF, the behavior of these
functions is undefined.
RETURN VALUE
The value returned is that of the converted letter, or c if the
conversion was not possible.
So in your example you can switch() with:
switch(tolower(menuChoice)) {
case('q'):
// ...
break;
case('s'):
// ...
break;
}
Of course you can use both toupper() and tolower(), with capital and non-capital letters.
You could (and for reasons of redability, should) before entering switch statement use tolower fnc on your var.
switch (toupper(choice))
{
case 'Q':...
}
...or tolower.
if you do
case('s' || 'S'):
// some code
default:
// some code
both s and S will be ignored and the default code will run whenever you input these characters. So you could decide to use
case 's':
case 'S':
// some code
or
switch(toupper(choice){
case 'S':
// some code.
toupper will need you to include ctype.h.

C++ enum from char

Ok, I'm new at C++. I got Bjarne's book, and I'm trying to follow the calculator code.
However, the compiler is spitting out an error about this section:
token_value get_token()
{
char ch;
do { // skip whitespace except '\n'
if(!std::cin.get(ch)) return curr_tok = END;
} while (ch!='\n' && isspace(ch));
switch (ch) {
case ';':
case '\n':
std::cin >> WS; // skip whitespace
return curr_tok=PRINT;
case '*':
case '/':
case '+':
case '-':
case '(':
case ')':
case '=':
return curr_tok=ch;
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '.':
std::cin.putback(ch);
std::cin >> number_value;
return curr_tok=NUMBER;
default: // NAME, NAME=, or error
if (isalpha(ch)) {
char* p = name_string;
*p++ = ch;
while (std::cin.get(ch) && isalnum(ch)) *p++ = ch;
std::cin.putback(ch);
*p = 0;
return curr_tok=NAME;
}
error("bad token");
return curr_tok=PRINT;
}
The error it's spitting out is this:
calc.cpp:42: error: invalid conversion from ‘char’ to ‘token_value’
token_value is an enum that looks like:
enum token_value {
NAME, NUMBER, END,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')'
};
token_value curr_tok;
My question is, how do I convert ch (from cin), to the associated enum value?
You can't implicitly cast from char to an enum - you have to do it explicitly:
return curr_tok = static_cast<token_value> (ch);
But be careful! If none of your enum values match your char, then it'll be hard to use the result :)
Note that the solutions given (i.e. telling you to use a static_cast) work correctly only because when the enum symbols were defined, the symbols (e.g. PLUS) were defined to have a physical/numeric value which happens to be equal to the underlying character value (e.g. '+').
Another way (without using a cast) would be to use the switch/case statements to specify explicitly the enum value returned for each character value, e.g.:
case '*':
return curr_tok=MUL;
case '/':
return curr_tok=DIV;
You need an explicit cast:
curr_tok = static_cast<token_value>(ch);
The reason is that it's dangerous to convert an integer type to an enum. If the value is not valid for the enum then behaviour is undefined. So the language doesn't let you do it accidentally with an implicit conversion. The explicit conversion is supposed to mean "I know what I'm doing, and I've checked that the value is valid".
I think I wouldn't try to explicitly set the values of the enum symbols and instead write a case for every symbol that in your switch statement. Doing it that way will probably be harder to debug if something goes wrong and the performance cost writing a case for every symbol is so low, that it's not even worth considering (unless you're writing for some kind of extremely low-end embedded system and probably still not worth it).
return curr_tok=(token_value)ch;