When is a string not a string?

Here's a curly one.
I'm new to Arduino and C++ but have extensive programming experience.
I have a project which uses keyboard input from IDE serial monitor.
It is String (1) a single character.
trimmed down

Serial.print( kbd );
if ( kbd == "C")
{ Serial.print ("Success");}
gives
C

and

kbd="C";
Serial.print( kbd );
if ( kbd == "C")
{ Serial.print ("Success");}
gives
C
Success

Any ideas???
Thanks

You trimmed too much code. Post the whole code.

And use code tags.

Here is more of the code. The whole project at last look was 34k long.
This is a function that will be expanded later.

// part of definitions & declarations
int target,DistCW,DistCCW;              //  Travel calculation variables
int x,y,z;                              //  temp variable
bool Origin;
String  kbd(1);

void setup() 
{
 // Debug
Serial.begin(9600);
//*********************************
 
/////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
        void LearnMode()
//
//  Programme up the EEPROM with various (semi)permanent data
//
//  All integers. Eprom data is stored BIGENDIAN.
//  When new, EEPROM full of 0xFF
//  Data order SpurCount, Counts per rev (CPR), Rear Track Offset,
//  Track #1 location, Track #2 location,,,,track #SpurCount location
//
//////////////////////////////////////////////////////////////////////

// Major commands (in order of performance)
//  "C" Spin for Counts per Rev
//  "S" Enter number of spurs
//  "E" Edit spur location 
//  "R" Set RearOffset
//  "N" return to normal mode
{
  fun:

//  Get major command
  Serial.println("C - Counts per Rev");
  Serial.println("S - Enter number of spurs");
  Serial.println("E - Edit spur locations");
  Serial.println("R - Set Rear Track Offset");
  Serial.println("N - return to normal mode");
  Serial.print("Command:");
  while(Serial.available()==0){}
  kbd=Serial.readString();
  kbd.toUpperCase();
  Serial.print(kbd);

     if (kbd=="C")
    {
      Serial.println("Counts per Rev");
      goto EndOfMajorCommand;
    }   
    if (kbd=="S")
    {
      Serial.println("Enter Spur Count:");
      goto EndOfMajorCommand;
    }
    if (kbd== "E")
    {
      Serial.println("Edit Spur location:");
      goto EndOfMajorCommand;
    }
    if (kbd== "R")
    {
      Serial.println("Set Rear Track Offset:");
      goto EndOfMajorCommand;
    }
    if (kbd== "N")
    {
      Serial.println("Return to Normal operation:");
      goto EndOfMajorCommand;
    }
    Serial.print("Unknown");
EndOfMajorCommand:

    
    goto fun;
}

Moderator edit: code tags added

If you're using Serial Monitor, it can send a line ending (carriage return and/or line feed); by default it adds those. So what you receive in that case is not "C" but "C\r\n" and hence the comparison fails.

This is what is happening in your case as C and Success are not displayed on the same line because kbd contains the line ending.

Thanks. Had to be something simple like that. How do I remove the ??
How can the String(1) contain 3 bytes?

With line endings enabled in serial monitor, when you enter and send 'C' what is actually sent is "C\r\n". The carriage return (\r) and line feed (\n) are added by serial monitor.

Set line endings to None and the carriage return and line feed will not be added.

String kbd(1); does not create a String object with 1 character; I'm not sure what it does but it's unusual in C++. Just use String kbd;.

String objects are dynamic; they will grow if needed. One problem is that they will never shrink so if you dump 100 characters in a String object and next clear it, it will still occupy 100 bytes.

On a side note, there is hardly ever a need for goto in C/C++ programs. In your example it's definitely not needed. Using goto will result in so-called spaghetti code that is difficult to follow and even more difficult to maintain.

Thanks again. I have set the monitor to no and it works but i would like to use it later.
I tried to use a nice 'case' statement but it went awry. I put most of the 'goto's in for debuging this issue and keeping the flow RealClear.

I have added
kbd.remove(1,5) // Which strips any extra stuff of the string
and it works !!!!!

Thanks
I owe you a cider or 5
Dave

In C/C++, switch/case works with numeric values; char, int and the likes.

In this case, you would be looking at if / else if ... / else.

Which language(s) are you familiar with?

Hi sterretje,
I started with Basic (of course) way back when... PDP11 RT11 multiuser basic.
I went on to machine code 6800 series, 6502 series, Z80. Most of my work was done on VAX/VMS command line interpreter (read DOS for supermini computers) and Fortran. A smattering of VAX assembler. Also quite a bit of systems management of windows network. Some older work on PDP8, Focal. And Most recently PIC assembler.
Gosh that sounds impressive. Most of my work was done at hardware level. I'm electronics rather than Software.
I have seen some C & C++ but I threw my hands in the air in horror and started tearing my (meagre) hair out in huge bunches.
I'm on a bit of a steep learning curve. DIscovering Where the answers are is at least half the battle.
Feeling much more hopeful about the future now that I can move the project on.

Thanks again.
Dave

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