Switch Statement with multi-dimensional array - c++

I have the following switch statement that actually works fine.
for (n = 0; n < 10; n++){
switch(results[r][n]){
case 0:
result[r][n] = "FAIL";
break;
case 1:
result[r][n] = "PASS";
break;
default:
break;
}
}
my question is WHY does this work, is it supposed to work or is there a much better way of doing this?
Is this how you are supposed to implement multi-dimensional arrays within a switch?
(r = 0 or 1)
How does the compiler know whether case 0: refers to r or n?

case 0 refers to results[r][n], not r or n. The values after case are matched to the value of the expression in the switch().
Look at a tutorial on switch-case
Your switch statement
switch(results[r][n]) {
case 0:
result[r][n] = "FAIL";
break;
case 1:
result[r][n] = "PASS";
break;
default:
break;
}
is equivalent to:
if (results[r][n] == 0)
result[r][n] = "FAIL";
else if (results[r][n] == 1)
result[r][n] = "PASS";
else
// do nothing
To anyone who was confused by the assignment of a string to something that should be an integer array, results is the integer[] array, result is a different variable that's a string[] array. As Robert notes below in the comments, a better naming system seems to be in order here.

Related

"Case label value has already appeared in this switch" when no duplicate cases can be found

I am working on programming the game 2048 in C++ as an exercise to get familiar with the language. Originally, the code wasn't throwing any errors but I was getting some logic errors in the final product so I thought that the problem could be that I was using the logic gates incorrectly. I looked it up and apparently the correct syntax for or was || when I was only using |, after I changed all of them to || my switch statement started saying that there were duplicate cases when it doesnt seem like there are any. what could this be caused by?
void slide(char direction){
int i;
int j;
switch (direction){
case 'W' || 'w':
for (j = 0; j < boardSize; j++){
int firstZero = -1;
for (i = 0; i < boardSize; i++){
if (board[i][j] == 0 && firstZero < 0){
firstZero = i;
}
if (board[i][j] > 0 && firstZero >= 0){
int temp = board[i][j];
board[i][j] = board[firstZero][j];
board[firstZero][j] = temp;
if (i != boardSize-1){
i = 0;
firstZero = -1;
}
}
}
}
break;
case 'A' || 'a':
break;
case 'S' || 's':
break;
case 'D' || 'd':
break;
}
}
You should look toward this approach:
case 'A': // If it is A, fall through
case 'a': // If it is a, pick this case
// Do something
break;
// Other cases...
This way, the choice will fall through.
On why your form of the condition does not work:
Condition - any expression of integral or enumeration type, or of a
class type contextually implicitly convertible to an integral or
enumeration type, or a declaration of a single non-array variable of
such type with a brace-or-equals initializer. - cppreference.com
A condition should evaluate to the value that is equal to the value of one of the constant_expressions on which it is tested on. This leads to the situation where the || is not evaluated as you expect; all the clauses evaluated to 1 (since both A and a aren't zero), hence the multiple cases are the same.
Bottom line: case label must be an integral constant expression.

Can anyone explain this function definition above the switch statement?

Here, I've made a function, that takes a character array and a single element array as input.
The input of expression is like "56+78", and then someone suggested this approach of using ascii code and for loops to store the two "numeric" substrings as two numbers, and used the character and switch statement below. But, I don't understand the part of storing these substrings as numbers and the asciicode concept.
void calculate(char ch[], char op[]){
int i;
int num1 = 0, num2 = 0;
for(i=0; ch[i]!='\0';i++)
{
if((int)ch[i]>=48 && (int)ch[i]<=57){
num1 = num1*10+(((int)ch[i])-48);
}
else{
op[0]=ch[i];
break;
}}
i++;
for(; ch[i]!='\0';i++)
{
if((int)ch[i] >= 48 && (int)ch[i] <= 57){
num2 = num2*10+(((int)ch[i])-48);
}
}
cout<<"OUTPUT: ";
switch(op[0])
{
case '+':
cout<<num1 + num2<<endl;
break;
case '-':
cout<<num1 - num2<<endl;
break;
case '*':
cout<<num1 * num2<<endl;
break;
case '/':
cout<<num1 / num2<<endl;
break;
}
}

C++ Array to one Int variable [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am curently working on one project, it's a converter... i am currently looking at Decimal to Hexadecimal. The code so far looks like this:
int rest;
int arr[50];
int i;
cout << N << " in decimal after conversation ";
while (N>0){
rest=N%16;
if (rest>9){
switch (rest){
case 10:
arr[i]='A';
break;
case 11:
arr[i]='B';
break;
case 12:
arr[i]='C';
break;
case 13:
arr[i]='D';
break;
case 14:
arr[i]='E';
break;
case 15:
arr[i]='F';
break;
}
}
else {
arr[i]=rest;
}
N=N/16;
i+=i;
}
cout<<arr;
return 1;
It's in function so dont be troubeled about the return 1...
my Question is:
is there any way possible to pull the whole array (for example containig [4,2,K,8] into one single variable? In the same exact order!
EDIT
aaaaaaaaaaaaaaaaaaaaaaaaaaand I'm back :D
i made a few changes to the program and now it is working and it goes like this:
int DecToHex(long long N)
{
int rest;
string s="";
while (N>0){
rest=N%16;
if (rest>9){
switch (rest){
case 10:
s="A"+s;
break;
case 11:
s="B"+s;
break;
case 12:
s="C"+s;
break;
case 13:
s="D"+s;
break;
case 14:
s="E"+s;
break;
case 15:
s="F"+s;
break;
}
}
else {
s = char(rest + 48) + s;
}
N=N/16;
}
if (s == "")
cout << "0";
else
cout << s;
return 1;
}
any idea how i could convert hexadecimal number to binary? the hexadecimal can be in string but the binary needs to be in int.
the structure of the program shoud be simmiliar to the this one of mine.
bud thnak's to everyone for the help!
is there any way possible to pull the whole array (for example containig [4,2,K,8] into one single variable?
You could use a std::string and pretend that it is one single variable but it is only an enhanced version of an array of chars.
BTW, couple of points that are unrelated to the above question.
You can simplify the switch statement. This was pointed out in a comment by #Kevin.
Use of arr[i]=rest; is wrong. It needs to be arr[i]=rest+'0';. This was pointed out in a comment by #scohe001.
Here's an updated version of the loop:
while ( N > 0 ) {
rest = N%16;
if (rest > 9){
arr[i] = 'A' + rest - 10;
}
else {
arr[i] = '0' + rest;
}
N = N/16;
i += i;
}
You can make that still simpler by using the suggestion by #Jarod:
char const* hex_letters = "0123456789ABCDEF";
while ( N > 0 ) {
rest = N%16;
arr[i] = hex_letters[rest];
N = N/16;
i += i;
}

if statement doesn't work in the block of switch?

I wrote a simple function as the following, but it does not work as expected, in C++, the if statement doesn't work in the block of switch?
void any2ten(string origin, int type)
{
if(! (type == 2 || type == 8 || type == 16))
{
cout << "unsupport this " << endl;
return;
}
int result = 0;
for (int index = 0; index < origin.length(); index++)
{
int tmp = 0;
switch (origin[index])
{
if (type == 16)
{
case 'F':
case 'f':
tmp = 15 * pow(type, index); break;
case 'E':
case 'e':
tmp = 14 * pow(type, index); break;
case 'D':
case 'd':
tmp = 13 * pow(type, index); break;
case 'C':
case 'c':
tmp = 12 * pow(type, index); break;
case 'B':
case 'b':
tmp = 11 * pow(type, index); break;
case 'A':
case 'a':
tmp = 10 * pow(type, index); break;
case '9':
tmp = 9 * pow(type, index); break;
case '8':
tmp = 8 * pow(type, index); break;
}
if (type == 8 || type == 16)
{
case '7':
tmp = 7 * pow(type, index); break;
case '6':
tmp = 6 * pow(type, index); break;
case '5':
tmp = 5 * pow(type, index); break;
case '4':
tmp = 4 * pow(type, index); break;
case '3':
tmp = 3 * pow(type, index); break;
case '2':
tmp = 2 * pow(type, index); break;
}
case '1':
tmp = 1 * pow(type, index); break;
case '0':
tmp = 0; break;
default:
cout << "wrong character has got" << endl;
return;
break;
}
result += tmp;
}
cout << result << endl;
}
while I test the function as any2ten("aa", 8), the result is 90 rather than wrong character.
is there anything wrong?
The if statement works fine in the block of a switch, you've just put it in a place where it never gets executed. The switch statement jumps to the corresponding case, that is its purpose. Whatever it jumps to, it will skip over the if, so the if never executes.
If you were to add code to make it possible to jump to between the switch and the if, then the if would execute normally. You could do this with a loop of any kind or a goto.
A default is only taken if no case is matched. Otherwise, the switch jumps to the matching case.
The switch statement doesn't work the way you imagine that it works. The way it behaves is not as a substitute of an if-else if-else, but somewhat differently.
Upon encountering the switch the process will jump to the code following the correct case. This means that you actually completely skip the execution of the if that you have placed there.
And yes, it does look weird, since you assume that because you have the curly braces you must execute if condition or not enter into them at all, but this is simply not the case.
Well the placement of your if-statement doesn't really make sense. The switch-statement jumps to the corresponding case and then exists, hence your if-statement won't be executed. And I wouldn't recommend to use goto, cause it's considered as a bad-practice.

int or char enum to int , not ASCII

I'm doing a poker game and have hit a wall. Any help would be great.
I have 12 card values. The values are chars either 2-9 or TJQKA (enumed below). I need to pass them to an int array such that their value is what gets passed (whether int value or enum value) instead of their ASCII.
for the example below, I want:
val[5] = {2,5,10,12,11}
instead of:
val[5] = {50,53,84,81,74}
enum cardvalues {T=10 , J , Q , K , A}
int val[5];
string value = "25TQJ";
for (int i = 0; i < 5; i++)
{
val[i] = value[i];
}
I would highly recommend using a map rather than an enum.
map<char,int> myCardMap;
myCardMap['T'] = 10;
...
val[i] = myCardMap[value[i]];
You'll need a conversion function:
int to_card(const char v)
{
switch(v)
{
case '2': return 2;
case '3': return 3:
// etc...
case 'T': return 10;
case 'J': return 11;
// etc...
}
Then in your loop:
val[i] = to_card(value[i]);
Make an std::map with ascii values in key and enum values in value
std::map<char, int> asciiMap;
asciiMap['T'] = 10;
asciiMap['J'] = 11;
//etc....
and then match the characters with the map
Generally you would need to convert the values from char to int. Here's the easiest way.
int convert_from_char(char c) {
if (c >= '2' && c <= '9') return (int)(c - '0');
else {
switch(c) {
case 'T': return (int)T;
case 'J': return (int)J;
case 'Q': return (int)Q;
case 'K': return (int)K;
case 'A': return (int)A;
default:
/* your program is borked. */
exit(1);
}
}
}
Then change your loop
for (int i = 0; i < 5; ++i)
val[i] = convert_from_char(value[i]);
I would suggest reconsidering using enums to represent cards, though. It will be easier in the long run just to make your own type, or use integers.
There is no way to directly convert from an enum symbol to the corresponding integer in C++ at runtime (obviously the compiler can do this at compile time). You may need to write a small helper function:
int card_value(char c) {
if (isdigit(c)) {
return c - '0';
} else {
switch (c) {
case 'T': return 10;
case 'J': return 11;
case 'Q': return 12;
case 'K': return 13;
case 'A': return 14;
default:
// whatever error handling here, such as:
return -1;
}
}
}
I suggest a switch:
switch (value[i]) {
case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
val[i] = atoi(value[i]);
break;
case 'T':
val[i] = 10;
break;
case 'J':
val[i] = 11;
break;
case 'Q':
val[i] = 12;
break;
case 'K':
val[i] = 13;
break;
case 'A':
val[i] = 14;
break;
default:
printf("Invalid character passed\n");
}
Create a function that will take a char argument (the ASCII card value, such as 'J') and return its numerical value. You might find the isdigit function and switch statement helpful.
If im understanding you correctly, you want to convert the string into card values (although for some reason you have the ace as 13 - id be tempted to say use 1 as the ace, although i can see you logic for it in a poker game).
Just using an enum wont help as at runtime you dont really have the information you need. An enum is a compile time concept mainly to assist the programmer and to handle checking.
There are many way to do what you want, you could have an array of index to char or a two entry array of char and value. For ease of alterations i would go with the following
typedef struct
{
char m_cCharacter;
int m_nValue;
} LOOKUP;
LOOKUP lookup_data[] = {
{ "2", 2 },
{ "3", 3 },
{ "4", 4 },
{ "5", 5 },
{ "6", 6 },
{ "7", 7 },
{ "8", 8 },
{ "9", 9 },
{ "T", 10 },
{ "J", 11 },
{ "Q", 12 },
{ "K", 13 },
{ "A", 14 }
};
int GetCharacter(char c)
{
int retval = -1; // Invalid
for(int i = 0; i < 13; i++)
{
if ( lookup_data[i].m_cCharacter == c )
{
retval = lookup_data[i].m_nValue;
break;
}
}
return retval;
}
for (int i = 0; i < 5; i++)
{
val[i] = GetCharacter(value[i]);
}
There are better ways with STL, and you should have more error checking and length of array detections, but hopefully you get the idea. You could use the enum in the lookup such as
{ "T", T },
If you preferred. Btw - i havent compiled this code so it probably wont build ;)
Try building a static array of size 256 such that the following gives the right answer:
for (int i = 0; i < 5; i++)
{
val[i] = AsciiToInt[value[i]];
}
That is,
AsciiToInt['2'] == 2
AsciiToint['T'] == 10,
AsciiToInt['J'] == 11
etc, but all invalid entries are zero.