Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way of implementing a good "itoa()" function?

Tags:

c

string

char

I was wondering if my implementation of an "itoa" function is correct. Maybe you can help me getting it a bit more "correct", I'm pretty sure I'm missing something. (Maybe there is already a library doing the conversion the way I want it to do, but... couldn't find any)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

char * itoa(int i) {
  char * res = malloc(8*sizeof(int));
  sprintf(res, "%d", i);
  return res;
}

int main(int argc, char *argv[]) {
 ...
like image 779
Nicolas C. Avatar asked Aug 09 '10 13:08

Nicolas C.


People also ask

What is the itoa function?

The itoa() function coverts the integer n into a character string. The string is placed in the buffer passed, which must be large enough to hold the output. The radix values can be OCTAL, DECIMAL, or HEX.

What does itoa stand for in C?

The itoa (integer to ASCII) function is a widespread non-standard extension to the standard C programming language.

How do you use atoi and itoa?

atoi is the 'ascii to integer' function and itoa is the reverse, the 'integer to ascii' function. You would use atoi to convert a string, say, “23557” to the actual integer 23557. Similarly, you would use itoa to convert an integer, say 44711, to the equivalent string “44711”. Very handy.


2 Answers

// Yet, another good itoa implementation
// returns: the length of the number string
int itoa(int value, char *sp, int radix)
{
    char tmp[16];// be careful with the length of the buffer
    char *tp = tmp;
    int i;
    unsigned v;

    int sign = (radix == 10 && value < 0);    
    if (sign)
        v = -value;
    else
        v = (unsigned)value;

    while (v || tp == tmp)
    {
        i = v % radix;
        v /= radix;
        if (i < 10)
          *tp++ = i+'0';
        else
          *tp++ = i + 'a' - 10;
    }

    int len = tp - tmp;

    if (sign) 
    {
        *sp++ = '-';
        len++;
    }

    while (tp > tmp)
        *sp++ = *--tp;

    return len;
}

// Usage Example:
char int_str[15]; // be careful with the length of the buffer
int n = 56789;
int len = itoa(n,int_str,10);
like image 139
Minh Nguyen Avatar answered Oct 27 '22 22:10

Minh Nguyen


  • Integer-to-ASCII needs to convert data from a standard integer type into an ASCII string.
  • All operations need to be performed using pointer arithmetic, not array indexing.
  • The number you wish to convert is passed in as a signed 32-bit integer.
  • You should be able to support bases 2 to 16 by specifying the integer value of the base you wish to convert to (base).
  • Copy the converted character string to the uint8_t* pointer passed in as a parameter (ptr).
  • The signed 32-bit number will have a maximum string size (Hint: Think base 2).
  • You must place a null terminator at the end of the converted c-string Function should return the length of the converted data (including a negative sign).
  • Example my_itoa(ptr, 1234, 10) should return an ASCII string length of 5 (including the null terminator).
  • This function needs to handle signed data.
  • You may not use any string functions or libraries.

.

uint8_t my_itoa(int32_t data, uint8_t *ptr, uint32_t base){
        uint8_t cnt=0,sgnd=0;
        uint8_t *tmp=calloc(32,sizeof(*tmp));
        if(!tmp){exit(1);}
        else{
            for(int i=0;i<32;i++){
            if(data<0){data=-data;sgnd=1;}
            if(data!=0){
               if(data%base<10){
                *(tmp+i)=(data%base)+48;
                data/=base;
               }
               else{
                *(tmp+i)=(data%base)+55;
                data/=base;
               }
            cnt++;     
            }
           }
        if(sgnd){*(tmp+cnt)=45;++cnt;}
        }
     my_reverse(tmp, cnt);
     my_memcopy(tmp,ptr,cnt);
     return ++cnt;
}
  • ASCII-to-Integer needs to convert data back from an ASCII represented string into an integer type.
  • All operations need to be performed using pointer arithmetic, not array indexing
  • The character string to convert is passed in as a uint8_t * pointer (ptr).
  • The number of digits in your character set is passed in as a uint8_t integer (digits).
  • You should be able to support bases 2 to 16.
  • The converted 32-bit signed integer should be returned.
  • This function needs to handle signed data.
  • You may not use any string functions or libraries.

.

int32_t my_atoi(uint8_t *ptr, uint8_t digits, uint32_t base){
    int32_t sgnd=0, rslt=0;
    for(int i=0; i<digits; i++){
        if(*(ptr)=='-'){*ptr='0';sgnd=1;}
        else if(*(ptr+i)>'9'){rslt+=(*(ptr+i)-'7');}
        else{rslt+=(*(ptr+i)-'0');}
        if(!*(ptr+i+1)){break;}
        rslt*=base;
    }
    if(sgnd){rslt=-rslt;}
    return rslt;
}
like image 43
Joseph Soliman Avatar answered Oct 27 '22 23:10

Joseph Soliman