Having issue wrapping my head around concatenation in c++

I am setting up a clock on my tft display and I want to control exactly how the date is displayed. I Figured out how to get the correct portion of the date and time but I want them to be combined into one string that I send to the display. I can send each portion individually but have to specify the location on the display.

I want it to display

Thu, Oct, 12, 2017

not

Thu , Oct , 12 , 2017

The spacing is a little exaggerated to show what I an talking about.

I thought this would work

String sDate;
  
  sDate= (rtc.getDOWStr(FORMAT_SHORT) + ", " + (rtc.getMonthStr(FORMAT_SHORT)) + ", " + (t.date) + ", " + (t.year));

But is gives me this error.

invalid operands of types 'char*' and 'const char [3]' to binary 'operator+'

I am using Arduino DUE with CTE TFT Sheild and a 7" TFT CPLD Display.

Here is the section of code

void UpdateClock(){

    // Get data from the DS3231
  t = rtc.getTime();
  String sDate;
  
  sDate= (rtc.getDOWStr(FORMAT_SHORT) + ", " + (rtc.getMonthStr(FORMAT_SHORT)) + ", " + (t.date) + ", " + (t.year));

//  rtc.getDOWStr(FORMAT_SHORT)
//  rtc.getMonthStr(FORMAT_SHORT)
// (t.date)
// (t.year))
  
  myGLCD.setFont(DotMatrix_M_Slash);
  myGLCD.print(rtc.getDOWStr((FORMAT_SHORT)),400, 10);// Day of Week
  myGLCD.print("," ,450, 10); //Day of Month
  myGLCD.print(rtc.getMonthStr((FORMAT_SHORT)) ,465, 10); // Month Name Abbreviated
  myGLCD.printNumI((t.date) ,400 ,50); // Day of Month
  myGLCD.printNumI((t.year) ,400, 100); // Year
  myGLCD.print(rtc.getTimeStr((FORMAT_SHORT)) ,400, 150); // Time of Day 24 Hour

}

Stay away from the String class, and especially stay away from using the + to put Strings together. It can shoot your heap memory full of holes and Arduino doesn't have any way to clean that up. Plus, lots of libraries are going to use the much safer char arrays and suddenly that String crutch gets hard to use.

You could use sprintf:

char buf[22];  // check this is big enough, I didn't count. 

sprintf(buf, "%s, %s, %02d, %04d", rtc.getDOWStr(FORMAT_SHORT), rtc.getMonthStr(FORMAT_SHORT), t.date, t.year);

But the easier method may be just to print the different pieces to the screen separately instead of trying to get it all done in one line.

The '+' operator only works for concatenation on String objects. For character arrays, character pointers, and string constants you would typically use a C library function like strcat(). BE WARNED: It is YOUR responsibility to make sure that your buffer is large enough to hold the combined strings.

Delta_G:
Stay away from the String class, and especially stay away from using the + to put Strings together. It can shoot your heap memory full of holes and Arduino doesn't have any way to clean that up. Plus, lots of libraries are going to use the much safer char arrays and suddenly that String crutch gets hard to use.

You could use sprintf:

char buf[22];  // check this is big enough, I didn't count. 

sprintf(buf, "%s, %s, %02d, %04d", rtc.getDOWStr(FORMAT_SHORT), rtc.getMonthStr(FORMAT_SHORT), t.date, t.year);




But the easier method may be just to print the different pieces to the screen separately instead of trying to get it all done in one line.

Thank you... This work perfectly.

I am not a c or c++ coder. I have always worked with TCL, and VBA,

This is all very new to me. I am really having difficulty getting the concepts down for some reason. Not sure why. I guess it will click eventually. I am sure part of it is time. I use it as a hobby so I don't get to use it very often.

What are the %s, %s, %02d, %04d for? I read the sprintf and the rest makes sense.

Am I reading it right?

%s means string
%02d means 2 digits
%04d means 4 digits

I this how sprintf sets up the formatting?

kilgorq:
Am I reading it right?

%s means string
%02d means 2 digits
%04d means 4 digits

I this how sprintf sets up the formatting?

Google printf, you're more likely to find a good list of formatters that way.

%s means string Yes, lower case s string, not String class. This is a null terminated char array
%02d means 2 digits Not just 2 digits, the 0 there means to pad with 0's if not long enough
%04d means 4 digits Same here, 4 digits 0 padded.

With a little study, you will find sprintf() a much easier and much more flexible method to get exactly the output format you want, than mucking around with String operators.

In any case, Strings will eventually cause your Arduino to malfunction.

The sprintf function uses printf format strings.

sprintf() is an extremely flexible and powerful function. However, rarely does one program use anything but a small fraction of that power. In the program below:

void setup() {
  char dow[] = "Thu";
  char month[] = "Oct";
  char result[20];
  char temp[5];
  int day = 12;
  int year = 2017;

  Serial.begin(9600);

 // sprintf(result, "%s, %s, %02d, %04d", dow, month, day, year);

  strcpy(result, dow);
  strcat(result, ", ");
  strcat(result, month);
  strcat(result, ", ");
  itoa(day, temp, DEC);
  strcat(result, temp);
  strcat(result, ", ");
  itoa(year, temp, DEC);
  strcat(result, temp);
   
  Serial.println(result);
}

void loop() {
}

the versions that uses sprintf() consumes 3348 bytes of flash and 206 bytes of SRAM. The alternative using the simple str*() functions uses 2084 bytes of flash and 190 bytes of SRAM. If you ever find yourself operating at the margins of memory, dropping back to less powerful functions might save the day.

You could recover the RAM (but not the program space) by using sprintf_P.

sprintf_P(result, PSTR("%s, %s, %02d, %04d"), dow, month, day, year);

Delta_G:
You could recover the RAM (but not the program space) by using sprintf_P.

sprintf_P(result, PSTR("%s, %s, %02d, %04d"), dow, month, day, year);

True. The SRAM requirement drops from 206 to 188 for this version and flash increase a few bytes to 3350.

Where'd I get the extra 2 bytes of SRAM from? I expected 190 like the str*() functions version you posted. I figured all I was getting back was the format string. Am I miscounting something? I would say it is temp getting optimized out, but that should be 5 bytes.

I don't know. I'm using 1.8.4 of the compiler. Try compiling it and see if your numbers are different.

econjack:
I don't know. I'm using 1.8.4 of the compiler. Try compiling it and see if your numbers are different.

Don't have one I can use right now (work computer, can't install). I'll take your word for it, I know you know what you're doing. I'm assuming your number is right and my thinking is wrong. I just want to know where I'm counting wrong. Nothing makes me crazier than knowing I got the answer wrong but not knowing why.

Where'd I get the extra 2 bytes of SRAM from? I expected 190 like the str*() functions version you posted.

206 - 188 is 18, if I calculated that correctly. I'm tired, and I've been drinking, so maybe I didn't.

"%s, %s, %02d, %04d"

This string literal is 18 characters, if I counted that correctly. I'm tired, and I've been drinking, so maybe I didn't.

18 == 18 most of the time.

You rock PaulS!

I don't know where I got 16. I guess the problem is that I haven't been drinking tonight.

What's sad is that I knew you were on tonight and when I posted that my first thought was, "Paul is going to come by and make me feel dumb for this." :slight_smile:

when I posted that my first thought was, "Paul is going to come by and make me feel dumb for this."

My job is done. I can go to bed now. 8)