(Menu) switch statement doesnt work properly after using Serial readString

Hi everyone! I'm new to arduino, and for my first project I wanted to build a simple serial menu. (code below)

while(!Serial.available());
char choice  = Serial.parseInt();
while(Serial.available()) Serial.read(); //get rid of CR

switch(choice) {
    case 1:
      // some code
      break;
    case 2:
    char content[1024];
    while(!Serial.available());
    String contentStr = Serial.readString();
    // some code to save contentStr  on sd card (it works);
    break;
case 3:
    // some code
    break;
case 4:
    // some code
    break;
default:
    // print invalid option
    break;
}

My problem is the following: case 2 does its job as it should, but my menu does not recognize any case below it (ex: if i press 5 i should get the invalid option message, if I press 4 the code from case 4 should execute, but I get nothing, etc.).
If i comment the line: String contentStr = Serial.readString(); in case 2 suddenly all the other cases work.
Can somebody explain to me this strange behaviour? I should mention that I use that same method of reading a string in other functions (not in a switch) and it works and I get the expected output.

Without knowing the rest of the code, hard to guess what's wrong. You use blocking while loops which is not a good idea. You could try to use Serial.readStringUntil('\n') instead of what you got. If you are using an AVR based MCU, the String data type may cause malfunction.

Which Arduino? What does the IDE say about the memory usage?

For e.g. an Uno, that is 50% of the available memory (RAM). And you will have to add that to the reported dynamic memory usage.

There are other problems; you might have to set the warning level to All in file -> preferences to see them.

C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2022814-3948-ykhd8q.21fs\sketch_sep14a\sketch_sep14a.ino: In function 'void loop()':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2022814-3948-ykhd8q.21fs\sketch_sep14a\sketch_sep14a.ino:23:10: warning: jump to case label [-fpermissive]
     case 3:
          ^
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2022814-3948-ykhd8q.21fs\sketch_sep14a\sketch_sep14a.ino:20:14: note:   crosses initialization of 'String contentStr'
       String contentStr = Serial.readString();
              ^~~~~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2022814-3948-ykhd8q.21fs\sketch_sep14a\sketch_sep14a.ino:26:10: warning: jump to case label [-fpermissive]
     case 4:
          ^
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2022814-3948-ykhd8q.21fs\sketch_sep14a\sketch_sep14a.ino:20:14: note:   crosses initialization of 'String contentStr'
       String contentStr = Serial.readString();
              ^~~~~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2022814-3948-ykhd8q.21fs\sketch_sep14a\sketch_sep14a.ino:29:5: warning: jump to case label [-fpermissive]
     default:
     ^~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2022814-3948-ykhd8q.21fs\sketch_sep14a\sketch_sep14a.ino:20:14: note:   crosses initialization of 'String contentStr'
       String contentStr = Serial.readString();
              ^~~~~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2022814-3948-ykhd8q.21fs\sketch_sep14a\sketch_sep14a.ino:17:12: warning: unused variable 'content' [-Wunused-variable]
       char content[1024];
            ^~~~~~~

Please provide your full sketch.

And thanks for using code-tags in your first post :+1:

You should not declare variables within a switch statement.

Move these statements before the switch statement OR add { } for everything in case 2:

The issue relates to variable scope.

1 Like

This shouldn’t compile, if there was error message post it

That’s ok if they are scoped

It does compile with warnings :wink:

The variable is not used so it is probably omitted by compiler so it compiles

To my knowledge, the compiler does not throw things away; the linker does. But I might be mistaken.

Because you initialize a local variable in 'case 2:' you can't reach any case after that without skipping the initialization. To fix it, either make the variable MORE local (local to case 2):

    case 2:
    {
      char content[1024];
      while(!Serial.available());
      String contentStr = Serial.readString();
      // some code to save contentStr  on sd card (it works);
    }
    break;

or don't initialize the local variable in the declaration:

    case 2:
    char content[1024];
    while(!Serial.available());
    String contentStr ;
    contentStr = Serial.readString();
    // some code to save contentStr  on sd card (it works);
    break;

Sorry for the late reply. Moving everything from case 2 to a new scope {} making everything 'more' local as you said fixed my bug. Thank you!

... as I mentioned in post #4... sigh.

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