calgorithm

Writing an integer to string function


i'm trying to write a function that take an integer in this interval [0;1000] and return the string of it.
Like for 234 it would be "234". But it don't work i don't know why do someone have an idea why ?

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

char* int_to_str(int input)
{
  char buffer[5];
  char* output;
  int input_temp;
  int count;
  
  input_temp = input;
  count = 4;
  
  while (count >= 0)
  {
    buffer[count] = '0';
    while (input_temp > pow(10, count))
    {
      input_temp -= pow(10, count);
      buffer[count] += 1;
    }
    count --;
  }
  output = NULL;
  output = malloc(sizeof(char) * (strlen(buffer) + 1));
  strcpy(output, buffer);
  return output;
}

I tested it with a printf, for 2 it returns 10000


Solution

  • In addition to the problems (> vs. >=, wrong order) answered here, code also has these problems:

    Weak pow()

    Some pow() do not provide the exact expected result for pow(10, count). Instead a value just less than a power of 10 is returned. When this is used (compare, subtract) with an integer, the result causes an off-by-1. (pow(10,4) might yield 9,999.9999...

    Avoid floating point functions for an integer problem.

    Missing '\0'

    In forming the string, OP's code fails to assign a null character.

    Be specific

    "I tested it with a printf, for 2 it returns 10000" deserves to have the code posted that did this.

    Assigning leading zero digits

    Since with 234, OP wants "234", OP's algorithm assigned a thousands digit of "0", even when the value is less than 1,000.


    Other points:

    No need to limit buffer size to so small

    Rather than char buffer[5];, consider a buffer that can handle all int. Commonly this is 12 for "-2147483648".

    Use protection

    Even though the goal is for values [0,1000], better code would check as values outside the range [0,9999] produce garbage results.

    .... or instead make the function work for all int.

    Test for allocation failure

    malloc() may return NULL and passing that to strcpy() is undefined behavior (UB).


    Alternative

    Code here to illustrates the idea: build from the least significant digit to most.

    The below has extra features like an arbitrary base. Thus it can be simplified given OP only needs 10.

    #include <assert.h>
    #include <limits.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <string.h>
    
    // Enough room INT_MIN as a binary string.
    #define MY_ITOA_BUF_SIZE (sizeof(int) * CHAR_BIT + 2)
    #define MY_ITOA_BASE_MIN 2
    #define MY_ITOA_BASE_MAX 36
    
    // Negative values result in a string beginning with a '-' for all bases
    //
    char* my_itoa(int i, int base) {
      char buf[MY_ITOA_BUF_SIZE];
      char *p = &buf[sizeof buf - 1];  // Point to last array element.
      assert(base >= MY_ITOA_BASE_MIN && base <= MY_ITOA_BASE_MAX);
    
      *p = '\0';
      int value = i < 0 ? i : -i;  // negative absolute value
      do {
        div_t qr = div(value, base);
        *(--p) = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-qr.rem];
        value = qr.quot;
      } while (value);
    
      if (i < 0) {
        *(--p) = '-';
      }
    
      size_t n_used = (size_t) (&buf[sizeof buf] - p);
      char *s = malloc(n_used);
      if (s) {
        strcpy(s, p);
      }
      return s;
    }