Using strcat to echo http read to a character array - whey these results?

Painful trial and error eventually gave me a method to read the reply from a web page and store it in a char array (so that I could - after a bit of manipulation, write it to SD file). But I don’t understand why some of the more obvious approaches wouldn’t work: can anyone point me to clear documentation, or if not, offer an explanation?

Here is a test Program that uses 10 different formats for a single character and shows what works and what doesn’t, for strcat and for serial.print:

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

  char testCA[100];
  //digit 0 output between double quotes  - strcat: ok          serial.print: ok
  //digit 1 output between single quotes  - strcat: ignored     serial.print: ok
  char two=     '2';    //                - strcat: ignored     serial.print: ok
  char three=   "3";    //                - strcat: gibberish   serial.print: gibberish
  char four[]=  "4";    //                - strcat: ok          serial.print: ok            
  char five[]=  {"5"};  //                - strcat: ok          serial.print: ok    
  char six[]=   {'6'};  //                - strcat: ok          serial.print: ok     
  char seven=   {'7'};  //                - strcat: gibberish   serial.print: ok     
  char eight[2]; //                       - strcat: ok          serial.print: ok
    eight[0]=   56;
    eight[1]=   0;
  char nine=    57;     //                - strcat: ignored     serial.print: ok       
  
  Serial.print("Testing Serial.print >");
  Serial.print("0");
  Serial.print('1');
  Serial.print(two);
  Serial.print(three);
  Serial.print(four);
  Serial.print(five);
  Serial.print(six);     
  Serial.print(seven);
  Serial.print(eight);
  Serial.print(nine);
  Serial.println("<");
  
  
  strcpy(testCA,"Testing strcat >");
  strcat(testCA,"0");         
  strcat(testCA,'1');         
  strcat(testCA,two);      
  strcat(testCA,three);       
  strcat(testCA,four);    
  strcat(testCA,five);
  strcat(testCA,six);        
  strcat(testCA,seven);   
  strcat(testCA,eight);    
  strcat(testCA,nine);  
  strcat(testCA,"<");
  Serial.println(testCA);
}

void loop() {}

This is the output:

Testing Serial.print >012*456789<
Testing strcat >0 ****a456**8<

(where * is a gibberish character that I can’t get to paste properly!)

and - for anyone facing the same issue - here is what I got working for the loop reading from http:

 char c = client.read();
 char appChar[2];
 appChar[0]=c;
 appChar[1]=0;
 strcat(thisCharArray,appChar);

Your code won’t even compile with IDE v1.6.9 without generating several errors. strcat relies on a zero terminated array to work properly.

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

  char testCA[100];
  //digit 0 output between double quotes  - strcat: ok          serial.print: ok
  //digit 1 output between single quotes  - strcat: ignored     serial.print: ok
  char two[]=     "2";    //                - strcat: ignored     serial.print: ok
  char three[]=   "3";    //                - strcat: gibberish   serial.print: gibberish
  char four[]=  "4";    //                - strcat: ok          serial.print: ok            
  char five[]=  "5";  //                - strcat: ok          serial.print: ok    
  char six[]=   "6";  //                - strcat: ok          serial.print: ok    
  char seven[]=   {'7',0};  //                - strcat: gibberish   serial.print: ok    
  char eight[2]; //                       - strcat: ok          serial.print: ok
    eight[0]=   56;
    eight[1]=   0;
  char nine[]=    {57,0};     //                - strcat: ignored     serial.print: ok      
  
  Serial.print("Testing Serial.print >");
  Serial.print("0");
  Serial.print('1');
  Serial.print(two);
  Serial.print(three);
  Serial.print(four);
  Serial.print(five);
  Serial.print(six);    
  Serial.print(seven);
  Serial.print(eight);
  Serial.print(nine);
  Serial.println("<");
  
  
  strcpy(testCA,"Testing strcat >");
  strcat(testCA,"0");        
  strcat(testCA,"1");        
  strcat(testCA,two);      
  strcat(testCA,three);      
  strcat(testCA,four);    
  strcat(testCA,five);
  strcat(testCA,six);        
  strcat(testCA,seven);  
  strcat(testCA,eight);    
  strcat(testCA,nine);  
  strcat(testCA,"<");
  Serial.println(testCA);
}

void loop() {}

A char is not a string, its actually an integer. strings can be thought of either as a pointer to char or a char array.

Whenever you mix char with string it doesn't work.

Whenever you try to use a non-string with strcat is doesn't work.

If you want to use strcat, use strings.

A C string is an array of characters with a null byte terminator, and the variable is effectively a pointer to char (ie to the zeroth entry in the array).

Note that a variable with an array type can treated by the compiler as an array (for instance sizeof() will return the total bytes used by the whole array), but at runtime it is passed about as a pointer to the zeroth element. So you can use char * and char[] interchangably for function parameters (this is a situation where the compiler cannot know the sizeof() the array since it can vary at runtime).

Basically its simplest to always write string variables like this:

char * s = "My string" ;   // A variable initialized to a particular string

void fn (char * s)  // passing a string to a function
{
  Serial.println (s) ;
}

Sometimes you need to allocate space dynamically for storing a string, in which case:

char s[30] ;

would be used - note that this can only hold strings upto 29 characters long (the null terminator takes one char space). This is never checked unless your code checks it - so always check it. The variable s can be passed around to any function wanting char *