How to convert an int to string in C?

后端 未结 10 1919
南方客
南方客 2020-11-22 02:51

How do you convert an int (integer) to a string? I\'m trying to make a function that converts the data of a struct into a string to save it in a fi

相关标签:
10条回答
  • 2020-11-22 03:11

    EDIT: As pointed out in the comment, itoa() is not a standard, so better use sprintf() approach suggested in the rivaling answer!


    You can use itoa() function to convert your integer value to a string.

    Here is an example:

    int num = 321;
    char snum[5];
    
    // convert 123 to string [buf]
    itoa(num, snum, 10);
    
    // print our string
    printf("%s\n", snum);
    

    If you want to output your structure into a file there is no need to convert any value beforehand. You can just use the printf format specification to indicate how to output your values and use any of the operators from printf family to output your data.

    0 讨论(0)
  • 2020-11-22 03:12

    Converting anything to a string should either 1) allocate the resultant string or 2) pass in a char * destination and size. Sample code below:

    Both work for all int including INT_MIN. They provide a consistent output unlike snprintf() which depends on the current locale.

    Method 1: Returns NULL on out-of-memory.

    #define INT_DECIMAL_STRING_SIZE(int_type) ((CHAR_BIT*sizeof(int_type)-1)*10/33+3)
    
    char *int_to_string_alloc(int x) {
      int i = x;
      char buf[INT_DECIMAL_STRING_SIZE(int)];
      char *p = &buf[sizeof buf - 1];
      *p = '\0';
      if (i >= 0) {
        i = -i;
      }
      do {
        p--;
        *p = (char) ('0' - i % 10);
        i /= 10;
      } while (i);
      if (x < 0) {
        p--;
        *p = '-';
      }
      size_t len = (size_t) (&buf[sizeof buf] - p);
      char *s = malloc(len);
      if (s) {
        memcpy(s, p, len);
      }
      return s;
    }
    

    Method 2: It returns NULL if the buffer was too small.

    static char *int_to_string_helper(char *dest, size_t n, int x) {
      if (n == 0) {
        return NULL;
      }
      if (x <= -10) {
        dest = int_to_string_helper(dest, n - 1, x / 10);
        if (dest == NULL) return NULL;
      }
      *dest = (char) ('0' - x % 10);
      return dest + 1;
    }
    
    char *int_to_string(char *dest, size_t n, int x) {
      char *p = dest;
      if (n == 0) {
        return NULL;
      }
      n--;
      if (x < 0) {
        if (n == 0) return NULL;
        n--;
        *p++ = '-';
      } else {
        x = -x;
      }
      p = int_to_string_helper(p, n, x);
      if (p == NULL) return NULL;
      *p = 0;
      return dest;
    }
    

    [Edit] as request by @Alter Mann

    (CHAR_BIT*sizeof(int_type)-1)*10/33+3 is at least the maximum number of char needed to encode the some signed integer type as a string consisting of an optional negative sign, digits, and a null character..

    The number of non-sign bits in a signed integer is no more than CHAR_BIT*sizeof(int_type)-1. A base-10 representation of a n-bit binary number takes up to n*log10(2) + 1 digits. 10/33 is slightly more than log10(2). +1 for the sign char and +1 for the null character. Other fractions could be used like 28/93.


    Method 3: If one wants to live on the edge and buffer overflow is not a concern, a simple C99 or later solution follows which handles all int.

    #include <limits.h>
    #include <stdio.h>
    
    static char *itoa_simple_helper(char *dest, int i) {
      if (i <= -10) {
        dest = itoa_simple_helper(dest, i/10);
      }
      *dest++ = '0' - i%10;
      return dest;
    }
    
    char *itoa_simple(char *dest, int i) {
      char *s = dest;
      if (i < 0) {
        *s++ = '-';
      } else {
        i = -i;
      }
      *itoa_simple_helper(s, i) = '\0';
      return dest;
    }
    
    int main() {
      char s[100];
      puts(itoa_simple(s, 0));
      puts(itoa_simple(s, 1));
      puts(itoa_simple(s, -1));
      puts(itoa_simple(s, 12345));
      puts(itoa_simple(s, INT_MAX-1));
      puts(itoa_simple(s, INT_MAX));
      puts(itoa_simple(s, INT_MIN+1));
      puts(itoa_simple(s, INT_MIN));
    }
    

    Sample output

    0
    1
    -1
    12345
    2147483646
    2147483647
    -2147483647
    -2147483648
    
    0 讨论(0)
  • 2020-11-22 03:14

    After having looked at various versions of itoa for gcc, the most flexible version I have found that is capable of handling conversions to binary, decimal and hexadecimal, both positive and negative is the fourth version found at http://www.strudel.org.uk/itoa/. While sprintf/snprintf have advantages, they will not handle negative numbers for anything other than decimal conversion. Since the link above is either off-line or no longer active, I've included their 4th version below:

    /**
     * C++ version 0.4 char* style "itoa":
     * Written by Lukás Chmela
     * Released under GPLv3.
     */
    char* itoa(int value, char* result, int base) {
        // check that the base if valid
        if (base < 2 || base > 36) { *result = '\0'; return result; }
    
        char* ptr = result, *ptr1 = result, tmp_char;
        int tmp_value;
    
        do {
            tmp_value = value;
            value /= base;
            *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
        } while ( value );
    
        // Apply negative sign
        if (tmp_value < 0) *ptr++ = '-';
        *ptr-- = '\0';
        while(ptr1 < ptr) {
            tmp_char = *ptr;
            *ptr--= *ptr1;
            *ptr1++ = tmp_char;
        }
        return result;
    }
    
    0 讨论(0)
  • 2020-11-22 03:17
    /*Function return size of string and convert signed  *
     *integer to ascii value and store them in array of  *
     *character with NULL at the end of the array        */
    
    int itoa(int value,char *ptr)
         {
            int count=0,temp;
            if(ptr==NULL)
                return 0;   
            if(value==0)
            {   
                *ptr='0';
                return 1;
            }
    
            if(value<0)
            {
                value*=(-1);    
                *ptr++='-';
                count++;
            }
            for(temp=value;temp>0;temp/=10,ptr++);
            *ptr='\0';
            for(temp=value;temp>0;temp/=10)
            {
                *--ptr=temp%10+'0';
                count++;
            }
            return count;
         }
    
    0 讨论(0)
  • 2020-11-22 03:30

    You can use sprintf to do it, or maybe snprintf if you have it:

    char str[ENOUGH];
    sprintf(str, "%d", 42);
    

    Where the number of characters (plus terminating char) in the str can be calculated using:

    (int)((ceil(log10(num))+1)*sizeof(char))
    
    0 讨论(0)
  • 2020-11-22 03:31

    The short answer is:

    snprintf( str, size, "%d", x );
    

    The longer is: first you need to find out sufficient size. snprintf tells you length if you call it with NULL, 0 as first parameters:

    snprintf( NULL, 0, "%d", x );
    

    Allocate one character more for null-terminator.

    #include <stdio.h> 
    #include <stdlib.h>
    
    int x = -42;
    int length = snprintf( NULL, 0, "%d", x );
    char* str = malloc( length + 1 );
    snprintf( str, length + 1, "%d", x );
    ...
    free(str);
    

    If works for every format string, so you can convert float or double to string by using "%g", you can convert int to hex using "%x", and so on.

    0 讨论(0)
提交回复
热议问题