42

I am using the itoa() function to convert an int into string, but it is giving an error:

undefined reference to `itoa'
collect2: ld returned 1 exit status

What is the reason? Is there some other way to perform this conversion?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shweta
  • 5,198
  • 11
  • 44
  • 58

14 Answers14

87

Use snprintf, it is more portable than itoa.

itoa is not part of standard C, nor is it part of standard C++; but, a lot of compilers and associated libraries support it.

Example of sprintf

char* buffer = ... allocate a buffer ...
int value = 4564;
sprintf(buffer, "%d", value);

Example of snprintf

char buffer[10];
int value = 234452;
snprintf(buffer, 10, "%d", value);

Both functions are similar to fprintf, but output is written into an array rather than to a stream. The difference between sprintf and snprintf is that snprintf guarantees no buffer overrun by writing up to a maximum number of characters that can be stored in the buffer.

artm
  • 17,291
  • 6
  • 38
  • 54
Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • 1
    Another difference between `sprintf` adn `snprintf` is the Standard they are described in: C89 (and later) for `sprintf`; C99 for snprintf. Notably the Windows library lacks the `snprintf` function or has a different behaviour than the Standard describes. – pmg Mar 09 '11 at 10:06
  • Is `snprintf`putting `'\0'` to my arrays last element ? So i can know where it is ending ? – Silidrone Nov 20 '16 at 09:30
  • @MuhamedCicak It will add the terminating '\0' provided that the value written and the termination '\0' can fit within the size parameter. You should check the return value, to see if it is the inputted size or greater. If it is the inputted size or greater, the result was truncated, and the buffer might not have a terminating '\0' character – Edwin Buck Nov 20 '16 at 17:59
  • @EdwinBuck This is correct, but to further clarify, i would say that you will always have a '\0' even when "truncation" occurs (unless you provided a size of zero, but that usage is only meaningful to determine the needed buffer size before making a second call). To be totally correct, one need to also check whether the returned value is negative, which happens "if an encoding error occurred" (whatever that means). In case of error, nothing specifies that the buffer will at least start with '\0' and horrors may ensue when trying to use it! – Johan Boulé Apr 08 '20 at 15:11
9

Use snprintf - it is standard an available in every compilator. Query it for the size needed by calling it with NULL, 0 parameters. Allocate one character more for null at the end.

int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);
user2622016
  • 6,060
  • 3
  • 32
  • 53
8

Before I continue, I must warn you that itoa is NOT an ANSI function — it's not a standard C function. You should use sprintf to convert an int into a string.

itoa takes three arguments.

  • The first one is the integer to be converted.
  • The second is a pointer to an array of characters - this is where the string is going to be stored. The program may crash if you pass in a char * variable, so you should pass in a normal sized char array and it will work fine.
  • The last one is NOT the size of the array, but it's the BASE of your number - base 10 is the one you're most likely to use.

The function returns a pointer to its second argument — where it has stored the converted string.

itoa is a very useful function, which is supported by some compilers - it's a shame it isn't support by all, unlike atoi.

If you still want to use itoa, here is how should you use it. Otherwise, you have another option using sprintf (as long as you want base 8, 10 or 16 output):

char str[5];
printf("15 in binary is %s\n",  itoa(15, str, 2));
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Mirwise Khan
  • 1,317
  • 17
  • 25
4

Better use sprintf(),

char stringNum[20];
int num=100;
sprintf(stringNum,"%d",num);
Shamim Hafiz - MSFT
  • 21,454
  • 43
  • 116
  • 176
  • 50 is a bit overkill - even a 64bit integer doesn't need 49 characters. and you have a typo in your sprintf call – ThiefMaster Mar 09 '11 at 07:22
  • 2
    Minor: `char stringNum[21];` needed for `-power(2,63)`. – chux - Reinstate Monica Apr 29 '15 at 03:33
  • I think it is worth mentioning in this context, for rookies and pros alike, that using fixed buffer sizes and `sprintf` is considered _bad practice_, and one of the most common root causes of memory corruption, security issues/exploits and other weird bugs. If possible, always use `snprintf` whenever you format strings into a buffer, and make sure you keep track of the size of the buffer used (also consider the trailing \0!) – origo Dec 02 '16 at 09:55
3

You can make your own itoa, with this function:

void my_utoa(int dataIn, char* bffr, int radix){
int temp_dataIn;
temp_dataIn = dataIn;
int stringLen=1;

while ((int)temp_dataIn/radix != 0){
    temp_dataIn = (int)temp_dataIn/radix;
    stringLen++;
}
//printf("stringLen = %d\n", stringLen);
temp_dataIn = dataIn;
do{
    *(bffr+stringLen-1) = (temp_dataIn%radix)+'0';
    temp_dataIn = (int) temp_dataIn / radix;
}while(stringLen--);}

and this is example:

char buffer[33];
int main(){
  my_utoa(54321, buffer, 10);
  printf(buffer);
  printf("\n");

  my_utoa(13579, buffer, 10);
  printf(buffer);
  printf("\n");
}
kenorb
  • 155,785
  • 88
  • 678
  • 743
3

Usually snprintf() is the way to go:

char str[16]; // could be less but i'm too lazy to look for the actual the max length of an integer
snprintf(str, sizeof(str), "%d", your_integer);
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
2
void itos(int value, char* str, size_t size) {
    snprintf(str, size, "%d", value);
}

..works with call by reference. Use it like this e.g.:

int someIntToParse;
char resultingString[length(someIntToParse)];

itos(someIntToParse, resultingString, length(someIntToParse));

now resultingString will hold your C-'string'.

Gewure
  • 1,208
  • 18
  • 31
2
char string[something];
sprintf(string, "%d", 42);
mehrdad khosravi
  • 2,228
  • 9
  • 29
  • 34
1

Similar implementation to Ahmad Sirojuddin but slightly different semantics. From a security perspective, any time a function writes into a string buffer, the function should really "know" the size of the buffer and refuse to write past the end of it. I would guess its a part of the reason you can't find itoa anymore.

Also, the following implementation avoids performing the module/devide operation twice.

char *u32todec( uint32_t    value,
                char        *buf,
                int         size)
{
    if(size > 1){
        int i=size-1, offset, bytes;
        buf[i--]='\0';
        do{
            buf[i--]=(value % 10)+'0';
            value = value/10;
        }while((value > 0) && (i>=0));
        offset=i+1;
        if(offset > 0){
            bytes=size-i-1;
            for(i=0;i<bytes;i++)
                buf[i]=buf[i+offset];
        }
        return buf;
    }else
        return NULL;
}

The following code both tests the above code and demonstrates its correctness:

int main(void)
{
    uint64_t acc;
    uint32_t inc;
    char buf[16];
    size_t bufsize;
    for(acc=0, inc=7; acc<0x100000000; acc+=inc){
        printf("%u: ", (uint32_t)acc);
        for(bufsize=17; bufsize>0; bufsize/=2){
            if(NULL != u32todec((uint32_t)acc, buf, bufsize))
                printf("%s ", buf);
        }
        printf("\n");
        if(acc/inc > 9)
            inc*=7;
    }
    return 0;
}
Safayet Ahmed
  • 698
  • 5
  • 14
0

see this example

#include <stdlib.h> // for itoa() call
#include <stdio.h>  

int main() {
    int num = 145;
    char buf[5];

    // convert 123 to string [buf]
    itoa(num, buf, 10);

    // print our string
    printf("%s\n", buf);

    return 0;
}

see this link having other examples.

Ishu
  • 12,797
  • 5
  • 35
  • 51
  • see this link it having some examples, http://www.daniweb.com/software-development/c/threads/11049 – Ishu Mar 09 '11 at 07:27
0

Like Edwin suggested, use snprintf:

#include <stdio.h>
int main(int argc, const char *argv[])
{
    int n = 1234;
    char buf[10];
    snprintf(buf, 10, "%d", n);
    printf("%s\n", buf);
    return 0;
}
beta
  • 2,380
  • 21
  • 38
0

If you really want to use itoa, you need to include the standard library header.

#include <stdlib.h>

I also believe that if you're on Windows (using MSVC), then itoa is actually _itoa.

See http://msdn.microsoft.com/en-us/library/yakksftt(v=VS.100).aspx

Then again, since you're getting a message from collect2, you're likely running GCC on *nix.

Dan
  • 1,258
  • 1
  • 10
  • 22
0

itoa() function is not defined in ANSI-C, so not implemented by default for some platforms (Reference Link).

s(n)printf() functions are easiest replacement of itoa(). However itoa (integer to ascii) function can be used as a better overall solution of integer to ascii conversion problem.

itoa() is also better than s(n)printf() as performance depending on the implementation. A reduced itoa (support only 10 radix) implementation as an example: Reference Link

Another complete itoa() implementation is below (Reference Link):

#include <stdbool.h> 
#include <string.h>

// A utility function to reverse a string 
char *reverse(char *str)
{
  char *p1, *p2;

  if (! str || ! *str)
        return str;
  for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
  {
        *p1 ^= *p2;
        *p2 ^= *p1;
        *p1 ^= *p2;
  }
  return str;
}
// Implementation of itoa() 
char* itoa(int num, char* str, int base) 
{ 
    int i = 0; 
    bool isNegative = false; 
  
    /* Handle 0 explicitely, otherwise empty string is printed for 0 */
    if (num == 0) 
    { 
        str[i++] = '0'; 
        str[i] = '\0'; 
        return str; 
    } 
  
    // In standard itoa(), negative numbers are handled only with  
    // base 10. Otherwise numbers are considered unsigned. 
    if (num < 0 && base == 10) 
    { 
        isNegative = true; 
        num = -num; 
    } 
  
    // Process individual digits 
    while (num != 0) 
    { 
        int rem = num % base; 
        str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0'; 
        num = num/base; 
    } 
  
    // If number is negative, append '-' 
    if (isNegative) 
        str[i++] = '-'; 
  
    str[i] = '\0'; // Append string terminator 
  
    // Reverse the string 
    reverse(str); 
  
    return str; 
} 

Another complete itoa() implementatiton: Reference Link

An itoa() usage example below (Reference Link):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
    int a=54325;
    char buffer[20];
    itoa(a,buffer,2);   // here 2 means binary
    printf("Binary value = %s\n", buffer);
 
    itoa(a,buffer,10);   // here 10 means decimal
    printf("Decimal value = %s\n", buffer);
 
    itoa(a,buffer,16);   // here 16 means Hexadecimal
    printf("Hexadecimal value = %s\n", buffer);
    return 0;
}
Onur Turhan
  • 1,237
  • 1
  • 13
  • 20
0
if(InNumber == 0)
{
    return TEXT("0");
}

const int32 CharsBufferSize = 64; // enought for int128 type
TCHAR ResultChars[CharsBufferSize];
int32 Number = InNumber;

// Defines Decreasing/Ascending ten-Digits to determine each digit in negative and positive numbers.
const TCHAR* DigitalChars = TEXT("9876543210123456789");
constexpr int32 ZeroCharIndex = 9; // Position of the ZERO character from the DigitalChars.
constexpr int32 Base = 10; // base system of the number.

// Convert each digit of the number to a digital char from the top down.
int32 CharIndex = CharsBufferSize - 1;
for(; Number != 0 && CharIndex > INDEX_NONE; --CharIndex)
{
    const int32 CharToInsert = ZeroCharIndex + (Number % Base);
    ResultChars[CharIndex] = DigitalChars[CharToInsert];
    Number /= Base;
}

// Insert sign if is negative number to left of the digital chars.
if(InNumber < 0 && CharIndex > INDEX_NONE)
{
    ResultChars[CharIndex] = L'-';
}
else
{
    // return to the first digital char if is unsigned number.
    ++CharIndex;
}

// Get number of the converted chars and construct string to return.
const int32 ResultSize = CharsBufferSize - CharIndex;
return TString{&ResultChars[CharIndex], ResultSize};