2

In Arduino code, I'm calling the getTextBounds() and print() API methods on my TFT handler object which accepts char* parameters and I have two integers holding a specific time's hour and minute part, for example:

int _hour = 7;
int _minute = 30;

I need to construct a char* variable that holds this string: 07:30. What is the simplest way to do that?

I tried this:

char* timestr = (_hour < 10 ? '0' : '') + _hour + ':' + (_minute < 10 ? '0' : '') + _minute;

But it gives me two kind of errors:

error: empty character constant
error: invalid conversion from 'int' to 'char*' [-fpermissive]
4

You don't want a char *, you want a character array, i.e. you have to allocate the memory for the string, not only for a pointer. That being said, you can build the string one character at a time like this:

char timestr[6];
timestr[0] = '0' + _hour / 10;
timestr[1] = '0' + _hour % 10;
timestr[2] = ':';
timestr[3] = '0' + _minute / 10;
timestr[4] = '0' + _minute % 10;
timestr[5] = '\0';

Then you can use timestr just as you would use a char*.

Edit 1: If you are not too short on RAM, you could allocate the string statically, and have the C runtime initialize the characters ':' and '\0' at program startup. Then you just have to set the four remaining chars on each conversion:

static char timestr[] = "--:--";  // initialized only once, with template
timestr[0] = '0' + _hour / 10;
timestr[1] = '0' + _hour % 10;
timestr[3] = '0' + _minute / 10;
timestr[4] = '0' + _minute % 10;

Edit 2: Maybe the “simplest”, in the sense “closest to what you had in mind”, would be to use a String object:

String timestr = String() + (_hour < 10 ? "0" : "") + _hour
    + ':' + (_minute < 10 ? "0" : "") + _minute;

You could print() that String directly, or retrieve the internal char* with the c_str() method.

I added this method only for completeness. Although simple in the source code, it would not be my first choice: it uses more memory, it is more CPU-intensive and – what worries me most – it uses heap allocation, which carries the risk of memory fragmentation.

  • That's one good answer! What if I would like to form this value: "03 Dec, 2016", where "Dec" comes from a char*[12] or char[12][3]? Should I manually set each piece of the timestr variable? – papaiatis Oct 20 '16 at 6:31
  • @papaiatis: Best option would probably be to use strftime(), from <time.h>, but it is only available on recent releases of avr-libc. You will have to test, as I don't know whether a time.h-enabled avr-libc is shipped with the Arduino IDE. If you don't have strftime(), sprintf_P() is a reasonable fallback. C.f. KIIV's answer. – Edgar Bonet Oct 20 '16 at 8:16
  • I ended up using your Edit1 solution. Thank you a lot for your efforts! :-) – papaiatis Oct 21 '16 at 19:00
1

What about using stdio.h? I know, it eats up some flash space, but:

#include <stdio.h>

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

void loop() {
  int _hour = 3;
  int _minute = 9;
  char buff[14]; // in worst case 6digigts per integer, separator and string terminating char

  sprintf_P(buff, PSTR("%02d:%02d"), _hour, _minute); // format string resides in flash (it needs special version of sprintf.
  // sprintf(buff, "%02d:%02d", _hour, _minute); // usual variant, but format is stored in RAM (and Flash too)

  Serial.println(buff);
  delay(5000);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.