In a switch case statement, it says "duplicate case value" comes up as an error. Anyone know why?
Asked Answered
O

6

10

I am working on a rock paper scissors program, but this time the computer chooses rock half the time, scissors a third of the time, and paper only one sixth of the time. The way I did this was I enumerated six possible computer choice values:

enum choicec {rock1, rock2, rock3, scissors1, scissors2, paper};
choicec computer;

But then, after the computer makes its choice, I have to convert these enumerated values to either rock, paper, or scissors. I did this using a switch-case statement:

switch(computer) {
        case rock1 || rock2 || rock3:
            c = 1;
            break;
        case scissors1 || scissors2: //ERROR!
            c = 3;
            break;
        case paper:
            c = 2;
            break;
    }

one is rock, two is paper, and three is scissors. However, on the line where I have error written in as a comment, it gives me this error: [Error] duplicate case value.

I'm not sure why. Any ideas?

Ollayos answered 20/6, 2013 at 22:39 Comment(4)
rock1 || rock2 || rock3 evaluates to true (1), like scissors1 || scissors2. You need separate labels, but can use fall-through, case rock1: case rock2: case rock3: c = 1; break;.Septime
You can't use || in case statements. Sorry :(Oshea
Wouldn't it have been a better design to have chosen an enum like { rock, scissors, paper }, and then simply structured your random number generator to provide the necessary statistical percentiles?Tilefish
thanks guys! that was all really helpful. now the program works.Ollayos
L
10

I am not sure what you doing, but switch statement should look like this

switch(computer) 
{
    case rock1:
    case rock2:
    case rock3:
        c = 1;
        break;
    case scissors1:
    case scissors2:
        c = 3;
        break;
    case paper:
        c = 2;
        break;
}
Leandro answered 20/6, 2013 at 22:43 Comment(0)
O
10

You can't use || in case branches. Sorry :(
When you use || it does a logical or on them, that says "is rock1 or rock2 or rock3 not a zero?". And the answer is yes, at least one of those is not zero. So rock1 || rock2 || rock3 is true, which is 1. And scissors1 || scissors is also true, which is 1. So you have two case branches for the 1 case.

You should simply use case fallthrough to select multiple conditions:

switch(computer) {
    case rock1: case rock2: case rock3:
        c = 1;
        break;
    case scissors1: case scissors2:
        c = 3;
        break;
    case paper:
        c = 2;
        break;
    default:
        std::cerr << "INVALID COMPUTER MOVE";
}

Also, I always have a default in my case switches. Sometimes mistakes happen, and we definitely want to know if it doesn't hit any of the case branches. I'm also pretty paranoid about missing else statements, but about half the time it's ok if there's no else.

Oshea answered 20/6, 2013 at 22:42 Comment(0)
L
10

I am not sure what you doing, but switch statement should look like this

switch(computer) 
{
    case rock1:
    case rock2:
    case rock3:
        c = 1;
        break;
    case scissors1:
    case scissors2:
        c = 3;
        break;
    case paper:
        c = 2;
        break;
}
Leandro answered 20/6, 2013 at 22:43 Comment(0)
J
4

That switch statement does not do what you think.

Each case defines one value that the value of computer is matched against. Combining several values with logical disjunction to give the value associated with a single case label does not make the corresponding block be entered when the value of computer is equal to any of those values, but rather when it is equal to the result of their logical OR combination. Not very meaningful, indeed.

This is how you could rewrite your switch statement in order to make more sense:

switch(computer) {
    case rock1: // Is it rock1?
    case rock2: // Or perhaps rock2?
    case rock3: // Or maybe rock3?
        c = 1;  // Well, if it's one of the above, do this...
        break;
    case scissors1: // OK, it wasn't. So is it scissors1?
    case scissors2: // Or scissors2?
        c = 3;      // If it's one of the above, do this...
        break;
    case paper: // So is it paper?
        c = 2;
        break;
    default: // Always better to be explicit about this
        break;
}
Jezabella answered 20/6, 2013 at 22:41 Comment(0)
R
3

Change it to:

switch(computer) {
    case rock1:
    case rock2:
    case rock3:
        c = 1;
        break;
    case scissors1:
    case scissors2:
        c = 3;
        break;
    case paper:
        c = 2;
        break;
}

rock1 || rock2 || rock3 and scissors1 || scissors2 are both expressions which evaluate to "true", hence the conflict.

Russo answered 20/6, 2013 at 22:41 Comment(0)
B
2

The expression used in the switch statement must be integral type ( int, char and enum). In the Switch statement, all the matching case execute until a break statement is reached and Two case labels cannot have the same value.

But in the above case with logical or condition. At first case: rock1 || rock2 || rock3: This will evaluate to 1 and second case scissors1 || scissors2: will also evaluate to 1. This is cause error as said Two case labels cannot have the same value.

This is the reason compiler complains and giving an error:

Compiler Error: duplicate case value

To solve this convert to

switch(computer) {
        case rock1: 
        case rock2:  
        case rock3:
            c = 1;
            break;
        case scissors1:
        case scissors2: //Now will not give any error here...
            c = 3;
            break;
        case paper:
            c = 2;
            break;
    }
Bonnibelle answered 12/6, 2019 at 17:48 Comment(0)
L
0
enum choicec {rock1, rock2, rock3, scissors1, scissors2, paper};
choicec computer;

This error also occurs if the variable after case has same value for two or more switch case for ex.

#define APPLE  0x0A
#define MANGO  0x0B
#define ORANGE 0x0A
switch(variable)
{
  case APPLE:
      // do something
      break;
  case MANGO:
      // do something
      break;  
  case ORANGE:
      // do something
      break;
}

Here the value of APPLE and ORANGE is duplicating so it will give an error: Compiler Error: duplicate case value

To fix this just make the macro values unique as follows:

#define APPLE  0x0A
#define MANGO  0x0B
#define ORANGE 0x0C
Least answered 19/7 at 5:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.