How to convert an int to string in C?

后端 未结 10 2138
南方客
南方客 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: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 
    #include 
    
    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
    

提交回复
热议问题