Use OR operator || in Switch Case

Greetings Arduino community,

Is it possible to use the OR operator in a Switch...Case statement?

Example:

char myMsg = "Hello World";
char myChar = myMsg[0];
switch (myChar) {
     case 'H' || 'h':
          // do something here
          break;
     case 'E' || 'e':
          // do something here
          break;
}

Hi,
I think no:

You cannot duplicate case parameters:

See error during compilation

sketch.ino: In function 'void loop()':
sketch.ino:8:22: error: invalid types 'char[int]' for array subscript
 char myChar = myMsg[0];
                      ^
sketch.ino:13:6: error: duplicate case value
      case 'E' || 'e':
      ^~~~
sketch.ino:10:6: note: previously used here
      case 'H' || 'h':
      ^~~~

Error during build: exit status 1

var: a variable whose value to compare with various cases. Allowed data types: int, char.

See : switch...case - Arduino Reference

Use like this:
case 'E' // do something here
break;
case 'e'
//do the same;
break

That's what I thought. I found I can use myMsg.toUpperCase() to accomplish what I need to do.

Thanks!

Duplicate the case one gor h and one for H.

You can stack cases, as long is the code doesn’t break; out, it will fall through

1 Like

Just use multiple case labels... like this.

  switch (myChar)
  {
    case 'H': case 'h':
      Serial.println("H/h found");
      break;
    case 'E': case 'e':
      Serial.println("E/e found");
      break;
    default:
      Serial.println("default");
      break;
  }
4 Likes

Thanks everyone for the helpful suggestions. I ended up using string.toUpperCase() so I didn't need to worry about the lower case letters.

NO!
A switch statement can just use "constant value", not any expression.
It acts like a "label", even not a variable is possible.

A switch looks like this:

if (var == 0x10) {
   //...do case
}
else if (var == 0x20) {
  //..do case
} else {
  //..do default
}

A switch generates a table: it compares variable against a "constant" !! value, and it branches, if value matches with the constant.
The

case VAL:

is really a fix constant, not any operation, not any variable. It is looking in a list with constant values and when the value matches - do it. But the list cannot be modified (is part of code generated).

case VAL :

must possible to be resolved as a constant value, a fix number.

Why not first convert character to upper case and then do comparison to switch case?

1 Like

He can do:

switch (myChar) {
   case : 'a':
   case : 'A':
      //now do for lower and capital letter 'A' - in the same way

You can "collapse" case statements (and use "fall through").

What is advantage of switch ... case versus if ... else if ... else? AFAIK result of both is the same.

@Smajdalf,

As far as I know, switch/case calculates the address of the first instruction in the selected case and jumps. if/else if might not do that. Fully up to the compiler to decide :wink:

It is rude to answer a question with a counter question.

Have you ever debugged a sketch with multiple if/elseIf constructs?

I do not agree that it is rude; after all, this whole forum is about helping and gaining knowledge. The only problem is that it might derail the topic.

That's what I ended up doing. Thanks!

The Case part of the Switch logic needs the 'break;' line to exit out of the switch when the Case is met. I forgot it in one of my cases and it went to the next Case wich had the 'break;' command.

YES, switch/case and if/else are not really the same.
It should just illustrate:
a case label (as a constant value) selects where to jump.

The switch statement creates a table, with label values to look for and then jump to the case block code (a relation between a constant value and a block of code).

My if/else was just to illustrate that just one label entry can be valid at a time. But case statements can "fall through" - and if/else cannot. If you skip the break - it executes also the next code block.

A switch/case is still (semantically like this):

if (var == case1value) { do this ...}
if (var == case2value) { do this ...}

caseXvalue must be a constant (cannot be any operation), in a case statement.
Difference is: here with IF I cannot fall though, but a switch/case can:

switch(var) {
   case case1value : do this...   //no break!
   case case2value : do this...   //a case1value matching executes also this code - fall trough
}

A switch/case is a bit "more powerful" as if/else (can fall through): just: the labels cannot be variables neither operations (must be a "compile constant" value).

Assuming all case blocks have a break (they do not fall through) - semantically the same as a nested if/else if: select one option as 1-of-N.

BTW:
a switch/case looks like this - or you can create your own similar code.
Use GOTO and labels (ugly, but this happens behind the scene with switch/case).
This example illustrates how switch/case works. And it has the beauty that you can use now operations in boolean check (switch/case cannot do - the case is constant value).

if (var == A) goto LA;
else if (var == B) goto LB;
else if (var == C) goto LC;
else goto LDEFAULT;

LA:
{
   //case LA : block
   ...
   //break is: not fall-through
   goto END;
}
LB:
{
   //case LB : block
   ...
   //now without a break - fall through - execute also the next case block
}
LC:
{
   //case LC : block
   ...
   //again with a break - do not fall-through to default
   goto END;
}
LDEFAULT:
{
   //the default: block
   ...
}
END:
//now end of switch

So, this code illustrates that:

  • switch/case is a "1-of-N" selection
  • the case is like a label - it must be a constant value
  • it can fall-through (without break)
  • has a default for the case that nothing matches

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.