Exercise 5-6-4 (conversions - Decimal to string)
Chapter_5 Exercise_5-6 Exercise_5-6-3 | Exercise_5-6-5 Exercise_5-7 |
Exercise 5-6 K&R, p. 107
Exercise 5-6. Rewrite appropriate programs from earlier chapters and exercises with pointers instead of array indexing. Good possibilities include getline() (Chapters 1 and 4), atoi(), itoa(), and their variants (Chapters 2, 3, and 4), reverse(), (Chapter 3), and strindex() and getop() (Chapter 4).
CONTENTS: itoa.c itoar.c utoa.c itob.c itoap.c
Note: For float or double to string, see the use of function gcvt() from stdlib.h in Exercises_8-2,3.
itoa.c K&R, p. 64 (Ex_3-4) download
#include <stdio.h> // for printf(), scanf()
#define SIZE 100 // array size (no of digits)
// reverse s, knowing its length:
void reverse(char *s, int len);
int itoa (int , char *); // int to string of chars
int main()
{
char digits[SIZE];
int n;
printf ("Give an integer: ");
scanf ("%d", &n);
itoa(n, digits);
printf ("%s\n", digits); // with an eventual sign
return 0;
}
// reverse s, knowing its length:
void reverse(char *s, int len)
{
char temp, *t = s+len-1;
while (s < t)
{
temp = *s;
*s = *t;
*t = temp;
s++;
t--;
}
}
// get the digits of n into s (convert n to a string of characters),
// return the length of s (no of digits, plus an optional sign):
int itoa (int n, char *s)
{
int sign = 1;
char *p = s;
if (n < 0)
{
sign = -1;
}
do
{ // get the digits in reverse order:
*p++ = (n % 10)*sign + '0'; // get next (last read) digit
// if n < 0, (n /= 10) <= 0, (n % 10) < 0
} while (n /= 10); // while ((n /= 10) != 0); // delete last digit
if (sign < 0) {*p++ = '-';} // first char after reverse
*p = '\0'; // end the string
reverse(s, p-s);
return p-s;
}
/*
gcc itoa.c -o itoa
./itoa
Give an integer: 0
0
./itoa
Give an integer: -1
-1
./itoa
Give an integer: 123
123
./itoa
Give an integer: -125
-125
./itoa
Give an integer: -2147483647 // INT_MIN+1
-2147483647
./itoa
Give an integer: -2147483648 // INT_MIN
-2147483648
./itoa
Give an integer: -2147483649 // INT_MIN-1
2147483647 // INT_MAX (underflow)
./itoa
Give an integer: -2147483650 // INT_MIN-2
2147483646 // INT_MAX-1 (modulo 2 arithmetic)
./itoa
Give an integer: 2147483647 // INT_MAX
2147483647
./itoa
Give an integer: 2147483648 // INT_MAX+1
-2147483648 // INT_MIN (overflow)
./itoa
Give an integer: 2147483649 // INT_MAX+2
-2147483647 // INT_MIN+1
*/
itoar.c K&R, p. 88 (Ex_4-12) download
#include <stdio.h> // for printf(), scanf()
#define SIZE 100 // array size (no of digits)
// recursive itoa():
int itoa(int , char*); // int to string (char array), return length
int main()
{
int i, n;
char array[SIZE];
printf("Type an integer, [+-]?[0-9]+\n");
scanf("%d", &n);
if (n < 0) {array[0] = '-';}
i = itoa(n, array);
array[i] = '\0';
printf("%s\n", array);
return 0;
}
// int n to string (char array), recursive itoa():
int itoa(int n, char *s) // start writing at position pos in array s
{ // return last position written (length of s)
int sign = 1;
int pos = 0; // position
if (n < 0)
{
sign = -1;
pos = 1;
}
if (n / 10) // if (n / 10 != 0)
{pos = itoa(n / 10, s);} // recursive call
*(s+pos) = (n % 10) * sign + '0';
pos++;
return pos;
}
/*
gcc itoar.c -o itoar
./itoar
Type an integer, [+-]?[0-9]+
0
0
./itoar
Type an integer, [+-]?[0-9]+
+0
0
./itoar
Type an integer, [+-]?[0-9]+
-0
0
./itoar
Type an integer, [+-]?[0-9]+
123
123
./itoar
Type an integer, [+-]?[0-9]+
+123
123
./itoar
Type an integer, [+-]?[0-9]+
-123
-123
./itoar
Type an integer, [+-]?[0-9]+
-2147483647 // INT_MIN+1 // limits.h
-2147483647
./itoar
Type an integer, [+-]?[0-9]+
-2147483648 // INT_MIN
-2147483648
./itoar
Type an integer, [+-]?[0-9]+
-2147483649 // INT_MIN-1
2147483647 // INT_MAX (underflow)
./itoar
Type an integer, [+-]?[0-9]+
-2147483650 // INT_MIN-2
2147483646 // INT_MAX-1 (modulo 2 arithmetic)
./itoar
Type an integer, [+-]?[0-9]+
2147483647 // INT_MAX
2147483647
./itoar
Type an integer, [+-]?[0-9]+
2147483648 // INT_MAX+1
-2147483648 // INT_MIN (overflow)
./itoar
Type an integer, [+-]?[0-9]+
2147483649 // INT_MAX+2
-2147483647 // INT_MIN+1
*/
utoa.c (ch3-utoa) download
#include <stdio.h> // for printf(), scanf()
#define SIZE 100 // array size (no of digits)
// reverse s, knowing its length:
void reverse(char *s, int len);
int utoa (unsigned , char *); // unsigned to string of chars
int main()
{
char digits[SIZE];
unsigned n;
printf ("Give an unsigned integer: ");
scanf ("%u", &n);
utoa(n, digits);
printf ("utoa(%u) = %s\n", n, digits);
return 0;
}
// reverse s, knowing its length:
void reverse(char *s, int len)
{
char temp, *t = s+len-1; // last char before '\0'
while (s < t)
{
temp = *s;
*s = *t;
*t = temp;
s++;
t--;
}
}
// get the digits of n into s (convert n to a string of characters),
// return the length of s (no of digits):
int utoa (unsigned n, char *s)
{
char *p = s;
do
{ // get the digits in reverse order:
*p++ = (n % 10) + '0'; // get next (last read) digit
} while (n /= 10); // while ((n /= 10) > 0); // delete last digit
*p = '\0'; // end the string
reverse(s, p-s);
return p-s; // length
}
/*
gcc utoa.c -o utoa
./utoa
Give an unsigned integer: 0
utoa(0) = 0
./utoa
Give an unsigned integer: -0
utoa(0) = 0
./utoa
Give an unsigned integer: +0
utoa(0) = 0
./utoa
Give an unsigned integer: 1
utoa(1) = 1
./utoa
Give an unsigned integer: +123
utoa(123) = 123
./utoa
Give an unsigned integer: -1
utoa(4294967295) = 4294967295 // UINT_MAX (limits.h)
./utoa
Give an unsigned integer: 4294967295 // UINT_MAX
utoa(4294967295) = 4294967295
./utoa
Give an unsigned integer: 4294967296 // UINT_MAX + 1
utoa(0) = 0 // (modulo 2 arithmetic - scanf() makes the conversion)
./utoa
Give an unsigned integer: 4294967297 // UINT_MAX + 2
utoa(1) = 1 // (modulo 2 arithmetic)
*/
itob.c K&R, p. 64 (Ex_3-5) download
#include <stdio.h> // for printf(), scanf()
#define SIZE 100 // array size (no of digits)
// reverse s, knowing its length:
void reverse(char *s, int len);
int itob (int n, char *s, int b); // int n to string of chars, base b
int main()
{
char digits[SIZE];
int n, base;
printf ("Give an integer: ");
scanf ("%d", &n);
printf ("Convert to base (2 <= base <= 36): ");
scanf ("%d", &base); // 0..9a..z = 36 chars
if (base < 2 || base > 36)
{
printf ("2 <= base <= 36\n");
printf ("Your input: %d\n", base);
return 1; // end program with an error message
}
itob(n, digits, base);
printf ("In base %d: %s\n", base, digits); // with an eventual sign
return 0;
}
// reverse s, knowing its length:
void reverse(char *s, int len)
{
char temp, *t = s+len-1;
while (s < t)
{
temp = *s;
*s = *t;
*t = temp;
s++;
t--;
}
}
// get the digits of n into s (convert n to a string of characters), base b,
// return the length of s (no of digits, eventual sign):
int itob (int n, char *s, int b)
{// both base b and remainder must be int, not unsigned, to prevent
// automatic conversion from int to unsigned in case n < 0
int sign = 1, remainder;
char *p = s;
if (n < 0)
{
sign = -1;
}
do
{ // get the digits in reverse order:
remainder = (n % b) * sign; // if n < 0, (n % b) < 0
// if remainder or b are unsigned, n < 0 is converted to a large positive number
if (remainder < 10)
{*p++ = remainder + '0';} // 0..9
else
{*p++ = remainder - 10 + 'a';} // a..z
// if n < 0, (n /= b) <= 0
} while (n /= b); // while ((n /= b) != 0); // delete last digit
// if b is unsigned, n < 0 is converted to a large positive (unsigned) number
if (sign < 0) {*p++ = '-';} // first char after reverse
*p = '\0'; // end the string
reverse(s, p-s);
return p-s;
}
/*
gcc itob.c -o itob
./itob
Give an integer: 0
Convert to base (2 <= base <= 36): 1
2 <= base <= 36
Your input: 1
./itob
Give an integer: 1
Convert to base (2 <= base <= 36): 37
2 <= base <= 36
Your input: 37
./itob
Give an integer: 123456
Convert to base (2 <= base <= 36): 36
In base 36: 2n9c
./itob
Give an integer: -123456
Convert to base (2 <= base <= 36): 36
In base 36: -2n9c
./itob
Give an integer: 123456
Convert to base (2 <= base <= 36): 2
In base 2: 11110001001000000
./itob
Give an integer: -123456
Convert to base (2 <= base <= 36): 2
In base 2: -11110001001000000
./itob
Give an integer: 32767
Convert to base (2 <= base <= 36): 16
In base 16: 7fff
./itob
Give an integer: 32767
Convert to base (2 <= base <= 36): 8
In base 8: 77777
./itob
Give an integer: 32767
Convert to base (2 <= base <= 36): 2
In base 2: 111111111111111
*/
itoap.c K&R, p. 64 (Ex_3-6) download
#include <stdio.h> // for printf(), scanf()
#define SIZE 100 // array size (no of digits)
#define WIDTH 8 // could also be 16, 32, or 64
// reverse s, knowing its length:
void reverse(char *s, int len);
// int to string of chars, minimum field width:
int itoap (int n, char *s, unsigned width);
int main()
{
char digits[SIZE];
int n;
printf ("Give an integer: ");
scanf ("%d", &n);
itoap(n, digits, WIDTH);
printf ("%s\n", digits); // with an eventual sign
return 0;
}
// reverse s, knowing its length:
void reverse(char *s, int len)
{
char temp, *t = s+len-1;
while (s < t)
{
temp = *s;
*s = *t;
*t = temp;
s++;
t--;
}
}
// get the digits of n into s[] (convert n to a string of characters),
// with a minimum field width (padded to the left if necessary),
// return length of s (digits, eventual sign):
int itoap (int n, char *s, unsigned width)
{
int sign = 1, diff;
char *p = s;
if (n < 0)
{
sign = -1;
}
do
{ // get the digits in reverse order:
*p++ = (n % 10)*sign + '0'; // get next (last read) digit
// if n < 0, (n /= 10) <= 0, (n % 10) < 0
} while (n /= 10); // while ((n /= 10) != 0); // delete last digit
if (sign < 0) {*p++ = '-';} // first char after reverse
diff = width-(p-s);
while (diff > 0) // while (diff)
{
*p++ = ' ';
diff--;
}
*p = '\0'; // end the string
reverse(s, p-s);
return p-s;
}
/*
gcc itoap.c -o itoap
./itoap
Give an integer: 0
0
./itoap
Give an integer: -1
-1
./itoap
Give an integer: 123
123
./itoap
Give an integer: -125
-125
./itoap
Give an integer: 1234567
1234567
./itoap
Give an integer: 12345678
12345678
./itoap
Give an integer: 123456789
123456789
./itoap
Give an integer: -123456
-123456
./itoap
Give an integer: -1234567
-1234567
./itoap
Give an integer: -12345678
-12345678
*/
Chapter_5 Exercise_5-6 Exercise_5-6-3 | BACK_TO_TOP | Exercise_5-6-5 Exercise_5-7 |
Comments
Post a Comment