Character Array Issues

Good evening all,

I am working on some code where I need to make an unsigned int into a string with a given number of digits in it for display on an LCD display. The following is the function I am using for this:

char * uintToString(unsigned int value, int numChars){

  char digitsChar[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
  char retVal[numChars + 1];
  int index = numChars - 1;
  
  // Initialize for given number of characters
  for (int i = 0; i < numChars; i++){
    retVal[i] = '0';
  }
  retVal[numChars] = '\0';

  // Convert the unsigned in to a string
  while (value >= 10){
    retVal[index--] = digitsChar[value % 10];
    value = value / 10;
  }
  retVal[index] = digitsChar[value];
  return retVal;
  
}

So, if I pass value = 1065 and numChars = 4, on return I get 0065. If I put in a Serial.print as shown here (or a delay, or almost any other statement) and change nothing else, I get 1065 as expected.

  // Convert the unsigned int to a string
  while (value >= 10){
    retVal[index--] = digitsChar[value % 10];
    value = value / 10;
  }
  retVal[index] = digitsChar[value];
  Serial.print(retVal);  // Can also replace with delay(10)
  return retVal;

Could someone please help me with figuring out why I get this behavior? I am totally stumped here.

Thanks in advance,
Rob Hix

Wow, my C/C++ is a little rustier than I thought. It has been 8-10 years since I touched C, so obviously there are some things I have forgotten.

That explanation makes total sense, thanks for the help and guidance.

Rob Hix

I need to make an unsigned int into a string with a given number of digits in it for display on an LCD display.

Why the need for conversion ? Can you not just print the unsigned int ?

sprintf() is very powerful and will work, but it's an H-bomb-to-kill-an-ant and uses more memory than you need because of unused features of the function. You might use something like:

void setup() {
  Serial.begin(9600);
  Serial.print("Enter an unsigned int: ");
}

void loop() {
  char input[6];
  int charsRead;
  int numChars = 5;     // We'll assume you want a field of 5 digits

  if (Serial.available() > 0) {
    charsRead = Serial.readBytesUntil('\n', input, sizeof(input) - 1);
    input[charsRead] = '\0';    // Make it a string...

    uintToString(input, numChars);     //Now pad the input

    Serial.print("Input = ");
    Serial.println(input);
    Serial.print("Enter an unsigned int: ");  
  }
}

/*****
 * Purpose: to pad number with leading 0's for desired field width
 * 
 * Parameter list:
 *  char *s         input digit characters
 *  int fieldWidth  the desired width of field
 *  
 * Return value:
 *  void
 *  
 * CAUTION: assumes s is big enough to hold digit chars, pad, and null
 * 
 */
void uintToString(char *s, int fieldWidth)
{
  char temp[6];
  int len = strlen(s);
  int i;
  if (len == fieldWidth) {      // Already desired width
    return;
  }
  len = fieldWidth - len;       // How many '0'

  temp[0]  = '\0';              // Since we use strcat()
  for (i = 0; i < len; i++) {
    strcat(temp, "0");          // Add leading '0'
  }
  strcat(temp, s);              // add original string on...
  strcpy(s, temp);              // copy all back to original string
}