exc/k&r/03-control-flow/03-06.c

63 lines
1.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <limits.h>
void itoa(int n, char s[], unsigned w);
/* passes args to itoa or INT_MIN if no arg is given */
int main(int argc, char *argv[])
{
int n, w;
n = (argc > 1) ? atoi(argv[1]) : INT_MIN;
w = (argc > 2) ? atoi(argv[2]) : (int)log10(abs(n)) + 1 + (n < 0);
if (w < 0) {
printf("error : invalid width %d\n", w);
return 1;
}
char s[w+1];
itoa(n, s, w);
printf("%s\n", s);
return 0;
}
void reverse(char *s);
/* itoa: convert n to characters (base 10) in s, pads with leading spaces
* to width w, truncates (left part) string of n if its is wider than w */
void itoa(int n, char s[], unsigned w)
{
int i = 0;
unsigned un = (n < 0) ? -n : n;
/* handle zero */
if (!n && w)
s[i++] = '0';
/* handle number */
for (; i < w && un > 0; un /= 10, i++) {
s[i] = un % 10 + '0';
}
/* handle sign */
if (n < 0 && i < w)
s[i++] = '-';
/* pad with spaces */
while (i < w)
s[i++] = ' ';
s[i] = '\0';
reverse(s);
}
/* reverse: reverses string s in place */
void reverse(char *s)
{
char c, *s2;
for (s2 = s + strlen(s) - 1; s < s2; s++, s2--)
c = *s, *s = *s2, *s2 = c;
}