K&R C Exercise 3-5: itob — Integer to Any Base String

Exercise 3-5. Write the function itob(n,s,b) that converts the integer n into a base b character representation in the string s. In particular, itob(n,s,16) should produce in s a hexadecimal string.

itob generalises itoa from base 10 to any base 2–36. The only change to the digit-extraction loop is replacing n % 10 with n % b and mapping the result to a character via a lookup string "0123456789abcdef...". Digits 0–9 map to '0''9'; digits 10–35 map to 'a''z'. The same negative-domain technique from Exercise 3-4 carries over: work with n negative throughout to handle INT_MIN without overflow. For each digit, -(n % b) is in range 0 to b−1 and safely indexes into digits[].

Solution

/* K&R Exercise 3-5 — itob: integer to base-b string
 * Compile: gcc -ansi -Wall ex3-5.c -o ex3-5 */
#include <stdio.h>
#include <string.h>
#include <limits.h>

static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";

void reverse(char s[])
{
    int i, j;
    char c;
    for (i = 0, j = strlen(s)-1; i < j; ++i, --j) {
        c = s[i]; s[i] = s[j]; s[j] = c;
    }
}

void itob(int n, char s[], int b)
{
    int i, sign;
    if (b < 2 || b > 36)
        return;
    sign = n;
    i = 0;
    do {
        s[i++] = digits[-(n % b)];
    } while ((n /= b) < 0);
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

int main(void)
{
    char s[64];

    itob(255, s, 16);     printf("255 base 16  = %s\n", s);    /* ff */
    itob(255, s, 2);      printf("255 base 2   = %s\n", s);    /* 11111111 */
    itob(255, s, 8);      printf("255 base 8   = %s\n", s);    /* 377 */
    itob(-255, s, 16);    printf("-255 base 16 = %s\n", s);    /* -ff */
    itob(INT_MIN, s, 10); printf("INT_MIN      = %s\n", s);    /* -2147483648 */
    return 0;
}

Note that itob(n, s, 10) is exactly itoa, and itob(n, s, 2) gives binary. The guard b < 2 || b > 36 prevents out-of-bounds indexing into digits[].

Compile and Run

gcc -ansi -Wall ex3-5.c -o ex3-5
./ex3-5

Sample Output

255 base 16  = ff
255 base 2   = 11111111
255 base 8   = 377
-255 base 16 = -ff
INT_MIN      = -2147483648

What This Exercise Teaches

  • Algorithm generalisation — parameterising the radix transforms itoa into a universal integer-to-string converter
  • Lookup table patterndigits[] maps integer 0–35 to the correct ASCII character without arithmetic
  • Reusing the negative-domain trick — the INT_MIN fix from Exercise 3-4 applies here unchanged
  • Input validation — guarding b < 2 || b > 36 prevents array overrun and undefined behaviour

Set Up Your C Environment

← Exercise 3-4  | 
Chapter 3 Solutions  | 
Exercise 3-6 →

Book:
The C Programming Language, 2nd Ed — Kernighan & Ritchie

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>