0

How do I properly convert integer into char array in C without using functions like sprintf? For exmample,

Input 
int data0 = 1010 
char data1 [];  

Output
data1[0] = '1'
data1[1] = '0'
data1[2] = '1'
data1[3] = '0'

How can I achieve this?

Thank you

Regards,

K.Son
  • 29
  • 2
  • 10

3 Answers3

1

For positive integers, this is quite simple... you can start by finding the last digit using the modulo operator...

78332 % 10 --> 2

Once you have the last digit, you can drop the last digit from the number by dividing by 10 (integer division):

78332 / 10 -> 7833

You can repeat this process until all digits have been extracted (i.e. until the result of the division is 0).

For negative numbers, you just check if the number is negative at the beginning, and if so you simply remember that fact and turn it into positive by changing the sign. When you finish generating the text representation, you must add - at the beginning if the number was originally negative.

A simple C version for the code would be something like this:

const char *myitoa(int x) {
    static char buf[100];
    int p = 98;
    int neg = x < 0;
    if (neg) x = -x;
    do {
        buf[--p] = '0' + x % 10;
        x = x/10;
    } while (x > 0);
    if (neg) buf[--p] = '-';
    return buf+p;
}

Note that this is a very simple implementation, not handling all cases (for example, there is a problem with the largest possible negative number, it doesn't work in a multi-threaded environment, and it overwrites the previous result every time you call it, so it's dangerous to call it in an interrupt handler, for example).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
6502
  • 112,025
  • 15
  • 165
  • 265
  • 1
    Note that `x = -x;` is _undefined behavior_ when `x == INT_MIN`. – chux - Reinstate Monica Jul 29 '23 at 01:33
  • @chux-ReinstateMonica: i was just adding comments about limitations, that one... it's not multithread-safe nor reentrant, always uses the same buffer... – 6502 Jul 29 '23 at 01:34
  • yngmo: I listed a few distinct "problems" of the code (there are indeed quite a few more I can think to). If they're real problems or not depends on the situation... Code that is bigger or just more complex and handles all of those cases/concerns can be a worse solution if those cases are not pertinent in the context. My english is not very good, probably things are now clearer thanks to the edits of Remy – 6502 Jul 29 '23 at 03:20
0

properly convert integer into char array

Form a function and provide a pointer to the char array, its size and the value.
Return an erorr flag.
Ref: INT_STRING_SIZE;

Starting with the least significant digit, assign that to the array (from the end). Divide the value by 10. Repeat until the value is 0. Copy into supplied buffer.

// Sample untested code.

#include <string.h>
#include <stddef.h>
#include <stdbool.h>
// Sample untested code.

// C99 or later...
// Return error flag
bool KSon_itoa(size_t sz, char *destination, int value) {
  char buf[INT_STRING_SIZE];
  size_t offset = INT_STRING_SIZE - 1;  // index the last element.
  buf[offset] = '\0';  // Null character terminate.
  bool sign = value < 0;

  // Work with the negative side as there are more negative values.
  if (value > 0) {
    value = -value; 
  }

  do {
    buf[--offset] = '0' - value % 10;
    value /= 10;
  } while (value);

  if (sign) {
    buf[--offset] = '-';
  }

  size_t size_used = (sizeof buf) - offset;
  if (size_used < sz) {
    // Not enough room.
    return true;
  }
  memcpy(destination, buf + offset, size_used);
  return false;
}

Works for the entire int range including INT_MIN and is thread safe.

[As question is a dupe, making this fun-to-do answer wiki.]

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
-1

If you don't want to use any pre defined functions like sprintf() or itoa() you can implement it from scratch using a while loop, extracting digits at each iteration.

First count the number of digits the input number has

int count = 0;
int temp = data0

if(data0==0){
    char data1[2];
    data1[0] = '0';
    data1[1] = '\0';
    // can return data1 if inside a function at this point
}

while(temp > 0){
    count++;
    temp /= 10;
}

declare the char array of calculated size

char data1[count+1];

now start extracting digits and add it to the array

temp = data0;
data1[count--]='\0';

while(temp > 0){
    int digit = temp%10;
    temp /= 10;
    data1[count--] = digit + '0';
    // count-- adds digits from the back of the array
}
  • Yes you are correct ! – Rituparna Warwatkar Jul 29 '23 at 01:38
  • `data[count--] = temp + '0';` Should be `data[count--] = digit + '0';` AND, your "string" doesn't appear to be terminated, either... AND, is it `data[]` or `data1[]`... All in all a somewhat hasty answer with lots of mistakes... – Fe2O3 Jul 29 '23 at 01:42
  • @Fe2O3 Sorry for that, but I have made the required changes... Would you please check once ? – Rituparna Warwatkar Jul 29 '23 at 01:47
  • In the first code block, `data1[]` is a local variable... It goes out of scope when the block ends (or return is executed.)... Your answer doesn't explain the `count+1` dimensioning and it is unclear of the scope of `data1` in the second code block... Finally, since the conversion function will likely be a function, there's no need for `temp`; just decay the parameter passed into the function... (Let's not go into negative numbers, I guess...) – Fe2O3 Jul 29 '23 at 01:57
  • @Rituparna Warwatkar, "can return data1 if inside a function at this point" is incorrect. Returning a pointer to a local object is bad as the object's lifetime ends with the function end. – chux - Reinstate Monica Jul 29 '23 at 14:29
  • @RituparnaWarwatkar, `data1[count--] = digit + '0';` will be a problem if `temp < 0` as `digit` may be less than zero too. – chux - Reinstate Monica Jul 29 '23 at 14:32