The C Programming Language, 2nd Edition, by Kernighan and Ritchie
Exercise 3.06 on page 64
Write a version of itoa
that accepts three arguments instead of two. The third argument is a minimum field width; the converted number must be padded with blanks on the left if necessary to make it wide enough.
Solution by Vidhan Gupta
/* Write a version of itoa that accepts three arguments instead of two. The third argument is a minimum field width; the converted number must be padded with blanks on the left if necessary to make it wide enough. */ #include <stdio.h> #include <string.h> #define MAXIMUM 50 void itoa(int n, char s[], int width); void reverse(char s[]); int main() { char s[MAXIMUM]; int n = -123456; int width = 15; itoa(n,s,width); printf("%s\n", s); return 0; } void itoa(int n, char s[], int width) { int i = 0, sign, gap; if ((sign = n) < 0) n = -n; do { s[i++] = n % 10 + '0'; } while (n /= 10); if (sign<0) s[i++]='-'; gap = width - strlen(s); if (gap>0) while (gap>0) { s[i++]=' '; gap--; } else{ while (gap<0) { i--; s[i]='\b'; gap++; } } reverse(s); } void reverse(char s[]){ int i,j,c; for(i = 0, j = strlen(s)-1; i<j; i++,j--) c=s[i],s[i]=s[j],s[j]=c; }
OUTPUT: -123456
Solution by Paul Griffiths
/* EX3_6.C ======= Suggested solution to Exercise 3-6 */ #include <stdio.h> #include <limits.h> void itoa(int n, char s[], int width); void reverse(char s[]); int main(void) { char buffer[20]; itoa(INT_MIN, buffer, 7); printf("Buffer:%s\n", buffer); return 0; } void itoa(int n, char s[], int width) { int i, sign; if ((sign = n) < 0) n = -n; i = 0; do { s[i++] = n % 10 + '0'; printf("%d %% %d + '0' = %d\n", n, 10, s[i-1]); } while ((n /= 10) > 0); if (sign < 0) s[i++] = '-'; while (i < width ) /* Only addition to original function */ s[i++] = ' '; s[i] = '\0'; reverse(s); } void reverse(char s[]) { int c, i, j; for ( i = 0, j = strlen(s)-1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } }
Solution by Luke Panayi
It seems I've interpreted the question differently to Paul and added the padding to the end of the string, rather than the beginning. I'm sure both are fine though!
#include <stdio.h> #define BUFFER 1000 int reverse(char s[]) { char ch; int i, j; for(j = 0; s[j] != '\0'; j++); --j; for(i = 0; i < j; i++) { ch = s[i]; s[i] = s[j]; s[j] = ch; --j; } return 0; } void itoa(int n, char s[], int w) { int i, sign, j; unsigned k; if ((sign = n) < 0) { k = -n; } else { k = n; } i = 0; do { s[i++] = k % 10 + '0'; } while ((k /= 10) > 0); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); if (i < w) { for (j=0; j <= (w-i); ++j) { s[i+j] = ' '; } s[i+j] = '\0'; //restore replaced null character } } int main() { char s[BUFFER]; itoa(-423,s,6); printf("%s\n",s); return 0; }
Solution by Miguel Degrossoli
/* Exercise 3-6. Write a version of "itoa" that accepts three arguments instead * of two. The third argument is a minimum field width; the converted number * must be padded with blanks on the left if necessary to make it wide * enough. */ #include <stdlib.h> #include <stdio.h> #include <limits.h> #define MAXLEN 13 /* maximum string length */ #define COUNT 8 /* how many numbers to convert */ void reverse(char s[]); void itoa(int n, char s[], int z); int main() { int i, number[] = {15, -15, 6, -6, 1983, -1983, INT_MIN, INT_MAX}; char s[MAXLEN]; for (i == 0; i < COUNT; i++) { itoa(number[i], s, 11); printf("%s\n", s); } exit(0); } void itoa(int n, char s[], int z) { int i, sign = 1; if (n < 0) sign = (-1); i = 0; do { s[i++] = (n % 10) * sign + '0'; } while ((n /= 10) != 0); if (sign < 0) s[i++] = '-'; z -= i; if (z > 0) do { s[i++] = ' '; } while (--z > 0); s[i] = '\0'; reverse(s); } void reverse(char s[]) { int i, n; char line[MAXLEN]; for (i = 0; s[i] != '\0' && i < MAXLEN; ++i) ; n = 0; if (i == 0 || s[i] == '\0') line[i] = '\0'; if (i > 0) { for (--i; i >=0; --i) { line[i] = s[n]; n++; } for (i = 0; line[i] != '\0'; i++) s[i] = line[i]; } }
miguel@Miguel-Notebook:~/Desenvolvimento/C$ ./exercise_3-6 15 -15 6 -6 1983 -1983 -2147483648 2147483647