Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arduino String Formatting Issue

I'm making an Arduino-powered clock, and in the process, I'm trying to format integers into two-digit formatted strings for the time read-out (e.g. 1 into "01").

The following gives me "error: expected primary-expression before '{' token":

char * formatTimeDigits (int num) {
  char strOut[3] = "00";
  if (num < 10) {
    strOut = {'0', char(num)};
  }
  else {
    strOut = char(num);
  }
  return strOut;
}

I'm trying to use it as follows:

void serialOutput12() {
  printWeekday(weekday); // picks the right word to print for the weekday
  Serial.print(", "); // a comma after the weekday
  Serial.print(hour12, DEC); // the hour, sent to the screen in decimal format
  Serial.print(":"); // a colon between the hour and the minute
  Serial.print(formatTimeDigits(minute)); // the minute
  Serial.print(":"); // a colon between the minute and the second
  Serial.print(formatTimeDigits(second)); // the second
}

Any ideas as to what I'm missing here?

like image 467
amb9800 Avatar asked Nov 24 '09 00:11

amb9800


People also ask

What does %d mean in Arduino?

%d is for a decimal signed int. %u is for an decimal unsigned int.

What is Snprintf in Arduino?

The snprintf() function formats and stores a series of characters and values in the array buffer. The snprintf() function accepts an argument 'n', which indicates the maximum number of characters (including at the end of null character) to be written to buffer.

Does Arduino support std :: string?

std::string is the most commonly used version, as it is part of the official C++ standard. However, on AVR Arduinos, you cannot use the C++ Standard Template Library (STL), so you cannot use std::string . That's why Arduino created its own String class, and this is the most widely used version in the Arduino ecosystem.

Can you format a string?

The %s symbol represents a format specifier for Strings, similar to how %d represents a format specifier for decimal numbers. There are many format specifiers we can use. Here are some common ones: %c - Character.


2 Answers

The curly-brace syntax is valid for initial declaration of a variable, but not for assignment after the fact.

Also, you are returning a pointer to an automatic variable, which is no longer validly allocated once returned (and will be smashed by the next call, such as to print). You need to do something like this:

void formatTimeDigits(char strOut[3], int num)
{
  strOut[0] = '0' + (num / 10);
  strOut[1] = '0' + (num % 10);
  strOut[2] = '\0';
}

void serialOutput12()
{
  char strOut[3]; // the allocation is in this stack frame, not formatTimeDigits

  printWeekday(weekday); // picks the right word to print for the weekday

  Serial.print(", "); // a comma after the weekday

  Serial.print(hour12, DEC); // the hour, sent to the screen in decimal format

  Serial.print(":"); // a colon between the hour and the minute

  formatTimeDigits(strOut, minute);
  Serial.print(strOut); // the minute

  Serial.print(":"); // a colon between the minute and the second

  formatTimeDigits(strOut, second);
  Serial.print(strOut); // the second
}
like image 177
Jeffrey Hantin Avatar answered Sep 29 '22 13:09

Jeffrey Hantin


In C, you can't directly set an array's contents with the = assignment operator (you can initialise an array, but that's a different thing, even though it looks similar).

Additionally:

  • It doesn't sound like the Wiring char(value) function/operator does what you want; and
  • If you want to return a pointer to that strOut array, you will have to make it have static storage duration.

The simple way to do what you want is sprintf:

char * formatTimeDigits (int num)
{
  static char strOut[3];

  if (num >= 0 && num < 100) {
    sprintf(strOut, "%02d", num);
  } else {
    strcpy(strOut, "XX");
  }

  return strOut;
}
like image 37
caf Avatar answered Sep 29 '22 11:09

caf