Exercise 3-5. Write the function
itob(n,s,b)that converts the integerninto a basebcharacter representation in the strings. In particular,itob(n,s,16)should produce insa 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
itoainto a universal integer-to-string converter - Lookup table pattern —
digits[]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 > 36prevents array overrun and undefined behaviour
Set Up Your C Environment
- Install GCC on Windows 11
- Install GCC on macOS
- Install GCC on Ubuntu/Linux
- VS Code for C Programming
← Exercise 3-4 |
Chapter 3 Solutions |
Exercise 3-6 →
Book:
The C Programming Language, 2nd Ed — Kernighan & Ritchie