Using a char array as a variable

I am missing something fundamental about character arrays. I am trying to assign new strings to an array, but String(), char(), = "xx"--none work for me. I have declared the array:

char new_row[21] ;

but the following code gives me the error

  • exit status 1*
  • incompatible types in assignment of 'char' to 'char [21]'*
void page_5() {
  new_row = "W.M.Valve_DIR .Open " ;
  //         01234567890123456789
  lcd.home() ;
  lcd.print(Rows) ;
  delay(3000) ;
  roll_rows() ;
  lcd.print(Rows) ;
  delay(3000) ;
  new_row = "W.M.Valve_PWR .On   " ;
  roll_rows() ;
  lcd.print(Rows) ;
  new_row = "Waiting for switch  " ;  
  delay(10000) ;
  }

If it was that easy. Check in to sprintf().

sprintf(new_row, "Waiting for switch ");

You need to look at strcpy, strncpy, or strcpy_P etc - you can't simply assign a string like that.

strcpy (new_row, "Waiting for switch");

(sprintf is too much overhead, a howitzer to swat a fly, IMHO)

Instead of the printf functions, you should use strncpy since it does no formatting and prevents buffer overflow which strcpy does not prevent.

CtrlAltElite:
(sprintf is too much overhead, a howitzer to swat a fly, IMHO)

Agreed, but it was what came to mind. It would work, the fly would be dead.

thanks all. Laughing about the dead fly.

So in my 30 minutes at lunch I had decided it was a problem with single and double quotes. That turned out to be wrong, but it raises a bigger question about Arduino documentation (maybe C++). I have not seen a good explanation of what the difference is between a string and a character array. Further, it's not well explained in any of the arduino.cc pages what the difference is (if I looked in memory or in the pointers, would I see a difference?) between

"A" and 'A' , or maybe even "ABC" and 'ABC' , except one is a string and the other a char
(and is 'ABC' three characters or just plain invalid?)

any links to a good explanation of this would be appreciated.

A string declared with double quotes ("") will always be null terminated whereas a sequence of characters declared with single quotes ('') will not. You should be able to declare an int with single quotes but not with double quotes since double quotes implies a null termination.

int valid = 'AB'; //Should be valid
int invalid = "AB"; //Should not

Since I almost never (99% never) use String, it is not hard for me to remember. If you put String out of your mind, then the only assignment available is by single quotes (char x='y';). Any double quotes will be used in the function calls strcpy, strncpy, printf, sprintf, and the like.

Following all the replies, I wound up looking at strlcat(). What I really want to do is concatenate a series of characters into the array, per the logic below:

new_row = "W.M." + "Valve_DIR " + ".Open " (20 characters into the 21 byte space)

Is there a single concatenation function for this, or do I need to do separate operations, eg,:

strcpy(new_row, "W.M.") ;
strlcat(new_row, "Valve_DIR ", 21) ;
strlcat(new_row, ".Open ", 21) ;

in the end I want to get to code that allows the text to be selected, based on what operation is being accomplished, eg, Open, Close, On, Off, etc. So I'm looking for a way to build an array (or three arrays) of constant text that can be selected (cut) and inserted into new_row[]. The text line will have three phrases, 4, 10, and 6 characters, to make the 20 character row.

For example, the 4 character phrases are W.M., R.M., W.B., R.B., R.M., R.B., W., and R.. The 6 character phrases are .Open, .Close, .On, .Off, .Yes, .No. (periods included) Then there's the 6 10-character phrases in the middle.

It turns out there are 29 possible combinations. I'm beginning to think that it might be easier to just build them all as static rows.... I've got plenty of memory.

new_row = "W.M." + "Valve_DIR " + ".Open "should be written new_row = "W.M."  "Valve_DIR "  ".Open "

CtrlAltElite:
new_row = "W.M." + "Valve_DIR " + ".Open "should be written new_row = "W.M."  "Valve_DIR "  ".Open "

That will fail, too. You can NOT use = to assign a new value to an array. Get over it.

Dr_Quark:
Is there a single concatenation function for this, or do I need to do separate operations, eg,:

   strcpy(new_row, "W.M.") ;

strlcat(new_row, "Valve_DIR ", 21) ;
  strlcat(new_row, ".Open ", 21) ;

If you are using string constants, just put them next to each other to concatenate.

For better safety your code should read:

   strlcpy(new_row, "W.M.", sizeof new_row) ;
   strlcat(new_row, "Valve_DIR ", sizeof new_row);
   strlcat(new_row, ".Open ", sizeof new_row) ;

Dr_Quark:
in the end I want to get to code that allows the text to be selected, based on what operation is being accomplished, eg, Open, Close, On, Off, etc. So I'm looking for a way to build an array (or three arrays) of constant text that can be selected (cut) and inserted into new_row[]. The text line will have three phrases, 4, 10, and 6 characters, to make the 20 character row.

For example, the 4 character phrases are W.M., R.M., W.B., R.B., R.M., R.B., W., and R.. The 6 character phrases are .Open, .Close, .On, .Off, .Yes, .No. (periods included) Then there's the 6 10-character phrases in the middle.

It turns out there are 29 possible combinations. I'm beginning to think that it might be easier to just build them all as static rows.... I've got plenty of memory.

Using arrays would allow for easier future expansion.

const char LeftPart[][5] =  {"W.M.","R.M.", "W.B.", "R.B.", "R.M.", "R.B.", "W.", "R."};
const char RightPart[][7] = {".Open", ".Close", ".On", ".Off", ".Yes", ".No"};
 
   strlcpy(new_row, LeftPart[3], sizeof new_row) ;
   strlcat(new_row, "Valve_DIR", sizeof new_row);
   strlcat(new_row, RightPart[2], sizeof new_row) ;