Character array appears to be growing

I have four four term character arrays:

char table1Orders[4];  // Character array for table 1 order
char table2Orders[4];  // Character array for table 2 order
char table3Orders[4];  // Character array for table 3 order

I also have another 12 term character array that was sent across an XBee connection and interpreted on the receiving end to be:

rrr0bgr0bggr

I am then running these through this sketch:
Note that I can't find how to initialize the character string normally. It was iterated with a for loop to be what I mentioned, an explanation on how to initialize a character string would be great. I can't figure how to initialize it with proper syntax.

int stateVal = 0;
int fourBlockTable;
char table1Orders[4];  // Character array for table 1 order
char table2Orders[4];  // Character array for table 2 order
char table3Orders[4];  // Character array for table 3 order
char orders[13] = {"rrr0bgr0bggr"};

void setup(){
  Serial.begin(9600);
}

void loop(){
// If the user sent c, calibrate the sensors
  if(orders[0] == 'c'){
    stateVal = 1;                                            // Calibrate the robot
  }

  // If the user sent r, reset the robot
  else if(orders[0] == 'e'){
    Serial.println("Emergency stop activated, shutting down robot.");
    stateVal = -1;                                           // Reset the robot
  }

  // Otherwise the orders are for the competition, parse the data and organize into tables
  else{
    for(int i = 0; i <= 3; i++){
      table1Orders[i] = orders[i];                            // Store block order to table array
    }
    // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------
    Serial.print("The orders for table 1 are: "); Serial.println(table1Orders);
    // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------

    for(int i = 4; i <= 7; i++){
      table2Orders[(i-4)] = orders[i];                            // Store block order to table array
    }
    // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------
    Serial.print("The orders for table 2 are: "); Serial.println(table2Orders);
    // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------

    for(int i = 8; i <= 11; i++){
      table3Orders[(i-8)] = orders[i];                            // Store block order to table array
                  Serial.println(table3Orders[(i-8)]);
    }
    // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------
    Serial.print("The orders for table 3 are: "); Serial.println(table3Orders);
    // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------

    // Identify which table is getting four blocks
    if(table1Orders[3] != '0'){
      fourBlockTable = 1;
      // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------
      Serial.println("The table requiring four blocks is table 1");
      // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------
    }

    else if(table2Orders[3] != '0'){
      fourBlockTable = 2;
      // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------
      Serial.println("The table requiring four blocks is table 2");
      // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------      
    }
    else{
      fourBlockTable = 3;
      // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------
      Serial.println("The table requiring four blocks is table 1");
      // DEBUGGING SERIAL PRINTS -------------------------------------------------------------------------------
    }
  }
}

When printing out the table1/2/3Orders variables I'm getting the following output:

The orders for table 1 are: rrr0
The orders for table 2 are: bgr0rrr0
The orders for table 3 are: bggrbgr0rrr0

This would imply that table2Orders is growing to an 8 bit char array that includes table1Orders, and likewise table3Orders has grown to a 12 bit array that includes table1Orders and table2Orders.

I have been messing with character arrays for a while and have been trying to wrap my head around their behavior. A new quirk seems to come up every time I think I have it figured out. How is printing out table1Orders also printing the other two orders? Or have table2Orders and table3Orders really been grown somehow?

this should give you a warning:

if not done already - activate the compiler warnings in your IDE in the settings.

changing to
char orders[12] = {"rrr0bgr0bggr"};

will bring you a

sketch_apr05a:6:34: error: initializer-string for array of chars is too long [-fpermissive]
 char orders[12] = {"rrr0bgr0bggr"};

to store 12 characters you will need 13 indices because of the null terminator

char orders[13] = {"rrr0bgr0bggr"};

will compile.

It does, I just included that to show that that's what it is supposed to say. The array was initialized in a for loop from an input into the serial monitor like this:

if (Serial2.available() > 12) {
    if (Serial2.read() != 255) {
      Serial.println("Bad data received, wiping the serial buffer.");
      while (Serial2.available() != 0) {
        Serial2.read();
      }
    }

    else {
      Serial.println("formatting orders");
      for (int i = 0; i <= 11; i++) {
        orders[i] = Serial2.read();
        Serial.print(orders[i]);
      }
      Serial.println();
      delay(20);
      while (Serial2.available() != 0) {
        Serial2.read();
      }
      stateVal = 0;
    }
  }

EDIT:
Yep, that compiled it!

@falcormoor
Did you forgot about string terminator byte?
To save string "rrr0" you need an array with five elements rather than four!
So to save "rrr0bgr0bggr" the size of array should be 13, not 12:

Also take a note about the difference between single and double quotes. To quote strings a double type MUST be used.

This is a distinction I have searched long and hard for an answer to but have not been able to find.
What is the difference between '' and ""?

one character or a string literal (which can consist of several characters and a final null terminator)

Do you want to describe your functionality because the code looks very ... hm ... strange anyway.
Maybe we can find a better solution for your problem?

You meant between 'a' and "a" ?

The first is a single char and the second is a string.
Therefore, the notation 'aaaa' is non-sense

I was trying to pick out the relevant part of my code for this issue from a very large overall project. Unfortunately that appears to have caused some considerable confusion. I am in class and will try to make this more clear after.

Ok, I am trying to make an array of single characters. That's how I have it built so I can call each element in the character array. One of my responses above shows how I actually built the orders[] array

that was ok - always show a minimum example to highlight your problem.

But what we can see here - I still think there is room for optimization - but for that we need more context.

1 Like

C-string is an array of single chars

char aa[4] = "yes";

yes, you will can

Serial.print(aa[2]);

will print "s"

Oh! I see that makes sense. What is the terminator element? Is it just an invisible thing that we as coders need to be aware that the compiler uses but poses no actual purpose for us?

the null byte

When you initialize an array this way:

char aa[4] = "yes";

compiler adds the aa[3] = '\0' behind the scene. But in any other circumstances you, as programmer, must to be aware about it.

ok, that makes sense, I knew there was additonal stuff put at the end of it but was confused what was causing it or how to work with it.
So that raises the question, how are the tableNOrders[] arrays changing their size? Do I need to adjust their initilization size to 5 and the problem will go away?

This page is familiar I think I came across it but was confused by it, my only exposure to C ++ is arduino so the syntax threw me off and I couldn't follow it.

I can only assume that the problem is in the lack of a terminator. All C string-oriented functions uses a null byte to determine the end of a string, the print() function also
Since your arrays doesn't had a terminator , the print function continued to print bytes from memory until the nearest zero byte

That makes a lot of sense! In that case, I should initialize the order arrays to have the null character. What would be the best way to do that? does doing

char table1Orders[5];

just automatically create a 4 byte character array with the end of string byte added to the end? Then I can just write into it like I am already doing? Or do I need to manually define that last terminator character?

For the global variables - yes. But not for local ones.... so it would be a good idea always initialize an empty char arrays with null:

char table1Orders[5] = {0};

I don't understand that syntax, could you explain it? does the ` add the null? or was that a typo? Does the 0 automatically put that at the end? Is the 0 the terminator character? I thought it was \0

just a typo, cleaned