Skip to main content
added 1914 characters in body
Source Link
chux
  • 33.7k
  • 2
  • 38
  • 92

. I really do not think this is a good place to use recursion given the potential for buffer overflow is a fair complication.

But if one must use recursion, consider adding error checking and test for various sorts of int including 0, INT_MAX, INT_MIN. Later

static char* itoa_helper(int number, size_t sz, char buffer[]) {
  if (sz == 0) {
    return NULL;
  }
  if (number <= -10) {
    buffer = itoa_helper(number / 10, sz - 1, buffer);
    if (buffer == NULL) {
      return NULL;
    }
    number %= 10;
  }
  *buffer = (char) ('0' - number);
  return buffer + 1;
}

char* itoa_recursive_alt(int number, size_t sz, char buffer[sz]) {
  if (sz == 0 || buffer == NULL) {
    return NULL;
  }
  char *s = buffer;

  if (number >= 0) {
    // Flip pos numbers to neg as neg range is greater.
    number = -number;
  } else {
    sz--;
    if (sz == 0) {
      *buffer = '\0';
      return NULL;
    }
    *s++ = '-';
  }
  s = itoa_helper(number, sz-1, s);
  if (s == NULL) {
    *buffer = '\0';
    return NULL;
  }
  *s = 0;
  return buffer;
}

int main(void) {
  char buf[100];
  int test[] = {123, 456, 0, -42, INT_MAX, INT_MIN};
  int n = sizeof test / sizeof *test;
  for (int i = 0; i < n; i++) {
    // char *s = itoa_recursive_alt(test[i], sizeof buf, buf);
    char *s = itoa_recursive_alt(test[i], sizeof buf, buf);
    if (s == NULL)
      s = "NULL";
    printf("%-11d <%s> <%s>\n", test[i], s, buf);
  }
  return 0;
}

Output

123         <123> <123>
456         <456> <456>
0           <0> <0>
-42         <-42> <-42>
2147483647  <2147483647> <2147483647>
-2147483648 <-2147483648> <-2147483648>

... Later

I really do not think this is a good place to use recursion given the potential for buffer overflow is a fair complication.

But if one must use recursion, consider adding error checking and test for various sorts of int including 0, INT_MAX, INT_MIN.

static char* itoa_helper(int number, size_t sz, char buffer[]) {
  if (sz == 0) {
    return NULL;
  }
  if (number <= -10) {
    buffer = itoa_helper(number / 10, sz - 1, buffer);
    if (buffer == NULL) {
      return NULL;
    }
    number %= 10;
  }
  *buffer = (char) ('0' - number);
  return buffer + 1;
}

char* itoa_recursive_alt(int number, size_t sz, char buffer[sz]) {
  if (sz == 0 || buffer == NULL) {
    return NULL;
  }
  char *s = buffer;

  if (number >= 0) {
    // Flip pos numbers to neg as neg range is greater.
    number = -number;
  } else {
    sz--;
    if (sz == 0) {
      *buffer = '\0';
      return NULL;
    }
    *s++ = '-';
  }
  s = itoa_helper(number, sz-1, s);
  if (s == NULL) {
    *buffer = '\0';
    return NULL;
  }
  *s = 0;
  return buffer;
}

int main(void) {
  char buf[100];
  int test[] = {123, 456, 0, -42, INT_MAX, INT_MIN};
  int n = sizeof test / sizeof *test;
  for (int i = 0; i < n; i++) {
    // char *s = itoa_recursive_alt(test[i], sizeof buf, buf);
    char *s = itoa_recursive_alt(test[i], sizeof buf, buf);
    if (s == NULL)
      s = "NULL";
    printf("%-11d <%s> <%s>\n", test[i], s, buf);
  }
  return 0;
}

Output

123         <123> <123>
456         <456> <456>
0           <0> <0>
-42         <-42> <-42>
2147483647  <2147483647> <2147483647>
-2147483648 <-2147483648> <-2147483648>
added 78 characters in body
Source Link
chux
  • 33.7k
  • 2
  • 38
  • 92

How does it look?

Not so good.

  1. Not thread safe.

  2. Does not handle negative numbers well.

  3. Forms "" with 0.

  4. Prone to buffer overflow.

  5. itoa() is not a standard function, yet it commonly returns a pointer.

A test harness

int main(void) {
  char buf[100];
  int test[] = {123, 456, 0, - 42, INT_MAX, INT_MIN};
  int n = sizeof test / sizeof *test;
  for (int i = 0; i < n; i++) {
    itoa(test[i], buf);
    printf("%-11d <%s>\n", test[i], buf);
  }
  return 0;
}

Output

123         <123>
456         <456>
0           <>
-42         <,.>
2147483647  <2147483647>
-2147483648 <./,),(-*,(>

It is not thread-safe due to the static, but is that an issue for a function such as this?

Yes. Thread safety is expected.


If so, how could I update that? What other ways could I make improvements to it?

... Later

How does it look?

Not so good.

  1. Not thread safe.

  2. Does not handle negative numbers well.

  3. Forms "" with 0.

  4. Prone to buffer overflow.

A test harness

int main(void) {
  char buf[100];
  int test[] = {123, 456, 0, - 42, INT_MAX, INT_MIN};
  int n = sizeof test / sizeof *test;
  for (int i = 0; i < n; i++) {
    itoa(test[i], buf);
    printf("%-11d <%s>\n", test[i], buf);
  }
  return 0;
}

Output

123         <123>
456         <456>
0           <>
-42         <,.>
2147483647  <2147483647>
-2147483648 <./,),(-*,(>

It is not thread-safe due to the static, but is that an issue for a function such as this?

Yes. Thread safety is expected.


If so, how could I update that? What other ways could I make improvements to it?

... Later

How does it look?

Not so good.

  1. Not thread safe.

  2. Does not handle negative numbers well.

  3. Forms "" with 0.

  4. Prone to buffer overflow.

  5. itoa() is not a standard function, yet it commonly returns a pointer.

A test harness

int main(void) {
  char buf[100];
  int test[] = {123, 456, 0, - 42, INT_MAX, INT_MIN};
  int n = sizeof test / sizeof *test;
  for (int i = 0; i < n; i++) {
    itoa(test[i], buf);
    printf("%-11d <%s>\n", test[i], buf);
  }
  return 0;
}

Output

123         <123>
456         <456>
0           <>
-42         <,.>
2147483647  <2147483647>
-2147483648 <./,),(-*,(>

It is not thread-safe due to the static, but is that an issue for a function such as this?

Yes. Thread safety is expected.


If so, how could I update that? What other ways could I make improvements to it?

... Later

Source Link
chux
  • 33.7k
  • 2
  • 38
  • 92

How does it look?

Not so good.

  1. Not thread safe.

  2. Does not handle negative numbers well.

  3. Forms "" with 0.

  4. Prone to buffer overflow.

A test harness

int main(void) {
  char buf[100];
  int test[] = {123, 456, 0, - 42, INT_MAX, INT_MIN};
  int n = sizeof test / sizeof *test;
  for (int i = 0; i < n; i++) {
    itoa(test[i], buf);
    printf("%-11d <%s>\n", test[i], buf);
  }
  return 0;
}

Output

123         <123>
456         <456>
0           <>
-42         <,.>
2147483647  <2147483647>
-2147483648 <./,),(-*,(>

It is not thread-safe due to the static, but is that an issue for a function such as this?

Yes. Thread safety is expected.


If so, how could I update that? What other ways could I make improvements to it?

... Later