Michał Szydłowski
Michał Szydłowski

Reputation: 3409

Conversion of integer to char array in C

I'm developing an ARM embedded application. I'm kind of stuck on a silly problem - I have an array of unsigned 8-bit integers:

uint8_t days[42] = { 0 };

It's initialized with some data - the initialization algorithm introduces a lot of variables confusing and irrelevant to the problem, so I will not repost it here. I see this array in the debugger variable watch, and I'm certain it is filled with integer values from 0 to 31.

I'd like to take any element of this array, say 15th, and convert it to char* so that it can be displayed on my LCD screen. I rewrite it using sprintf function:

char d[3] = { '0', '0', '0' };
sprintf(d, "%d", days[15]);

Just one note: no, I can't use the stdlib itoa() function, because it does not conform to MISRA-C standards, which I am obliged to follow.

As a result, I only get a binary zero value in my d buffer. Any ideas?

Upvotes: 2

Views: 8205

Answers (2)

Bruce
Bruce

Reputation: 2310

#include "stdafx.h"
#include <stdio.h>

int days[2] = {12,14};
char d[3] = {'0', '0', 0};

int _tmain(int argc, _TCHAR* argv[])
{
    d[0] = days[1] / 10 + 0x30;  // convert 10's digit to ascii
    d[1] = days[1] % 10 + 0x30;  // convert 1's digit to ascii

    // Debugging help
    printf(d);
    getchar();

    return 0;
}

Upvotes: 0

Lundin
Lundin

Reputation: 213721

For MISRA-C compliance, you can certainly not use sprintf() or anything else from stdio.h either. You generally want to avoid sprintf like the plague on any embedded system anyhow.

Writing a simple decimal integer to string conversion routine is quite basic stuff... here's my attempt of a MISRA-C (2004 and 2012) compatible version:

#include <stdint.h>

void dec_to_str (char* str, uint32_t val, size_t digits);

int main (void)
{
  char str[3u + 1u]; // assuming you want null terminated strings?

  dec_to_str(str, 31u, 3u);

  return 0;
}


void dec_to_str (char* str, uint32_t val, size_t digits)
{
  size_t i=1u;

  for(; i<=digits; i++)
  {
    str[digits-i] = (char)((val % 10u) + '0');
    val/=10u;
  }

  str[i-1u] = '\0'; // assuming you want null terminated strings?
}

Note: the uint32_t variable could get swapped out for an uint8_t, but then you need to add type casts all over the place, to prevent implicit type promotions, as required by MISRA. The code will then turn really ugly, like this:

 str[digits-i] = (char)(uint8_t)((uint8_t)(val % 10u) + '0');

The only sane thing to do then, is to split that mess into several lines:

uint8_t ch = (uint8_t)(val % 10u);
ch = (uint8_t)(ch + '0');
str[digits-i] = (char)ch;

Upvotes: 3

Related Questions