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).
#include <stdio.h> // for printf(), scanf()
#define LENGTH 15 // max length of string
int atoi(char *s); // string to integer
int main()
{
char s[LENGTH];
printf("Enter a decimal number [+-]?[0-9]+\n");
scanf("%s", s);
printf("atoi(%s): %d\n", s, atoi(s));
return 0;
}
int atoi(char *s) // string to integer
{
if (*s == '\0') // empty string
{ // not a valid decimal
printf("\"%s\" is not a valid number\n", s);
return 0; // should handle the error with an exception as we cannot
} // signal the error here with a returned value
// here 's' is not empty
int n = 0, sign = 1;
char *p = s;
if (*p == '-') // negative number
{
sign = -1;
p++; // skip optional sign
}
else if (*p == '+') // positive number
{
p++; // skip optional sign
}
if (*p == '\0')
{
printf("\"%s\" is not a valid decimal number\n", s);
return 0;
}
while (*p != '\0')
{
if (*p >= '0' && *p <= '9')
{n = n*10 + (*p - '0');}
else // not a valid decimal
{
printf("\"%s\" is not a valid decimal number\n", s);
return sign * n;
}
p++;
}
return sign * n;
}
/*
gcc atoi.c -o atoi
./atoi
Enter a decimal number [+-]?[0-9]+
0
atoi(0): 0
./atoi
Enter a decimal number [+-]?[0-9]+
-1
atoi(-1): -1
./atoi
Enter a decimal number [+-]?[0-9]+
+2
atoi(+2): 2
./atoi
Enter a decimal number [+-]?[0-9]+
a
"a" is not a valid decimal number
atoi(a): 0
./atoi
Enter a decimal number [+-]?[0-9]+
+
"+" is not a valid decimal number
atoi(+): 0
./atoi
Enter a decimal number [+-]?[0-9]+
-
"-" is not a valid decimal number
atoi(-): 0
./atoi
Enter a decimal number [+-]?[0-9]+
1.2
"1.2" is not a valid decimal number
atoi(1.2): 1
./atoi
Enter a decimal number [+-]?[0-9]+
-1.2
"-1.2" is not a valid decimal number
atoi(-1.2): -1
./atoi
Enter a decimal number [+-]?[0-9]+
32767 // SHRT_MAX (limits.h)
atoi(32767): 32767
./atoi
Enter a decimal number [+-]?[0-9]+
2147483647 // INT_MAX (limits.h)
atoi(2147483647): 2147483647
./atoi
Enter a decimal number [+-]?[0-9]+
2147483648 // INT_MAX + 1
atoi(2147483648): -2147483648 // INT_MIN (modulo 2 arithmetic)
./atoi
Enter a decimal number [+-]?[0-9]+
-2147483648 // INT_MIN
atoi(-2147483648): -2147483648
./atoi
Enter a decimal number [+-]?[0-9]+
-2147483649 // INT_MIN - 1
atoi(-2147483649): 2147483647 // INT_MAX (modulo 2 arithmetic)
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf(), scanf()
#define LENGTH 20 // max length of string
unsigned atou(char *s); // string to unsigned integer (decimal)
int main()
{
char s[LENGTH];
printf("Enter an unsigned decimal number [+]?[0-9]+\n");
scanf("%s", s);
printf("atou(%s): %u\n", s, atou(s));
return 0;
}
unsigned atou(char *s) // string to unsigned integer (decimal)
{
if (*s == '\0') // empty string
{ // not a valid decimal
printf("\"%s\" is not a valid number\n", s);
return 0; // should handle the error with an exception as we cannot
} // signal the error here with a returned value
// here 's' is not empty
int n = 0;
char *p = s;
if (*p == '-' && *(p+1) == '0' && *(p+2) == '\0')
{return 0;}
if (*p == '+')
{
p++; // skip optional sign
}
if (*p == '\0' || *p == '-' && *(p+1) == '\0')
{
printf("\"%s\" is not a valid number\n", s);
return 0;
}
while (*p != '\0')
{
if (*p >= '0' && *p <= '9')
{n = n*10 + (*p - '0');}
else // not a valid decimal
{
printf("\"%s\" is not a valid unsigned decimal number\n", s);
return n;
}
p++;
}
return n;
}
/*
gcc atou.c -o atou
./atou
Enter an unsigned decimal number [+]?[0-9]+
0
atou(0): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
-0
atou(-0): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
-0.0
"-0.0" is not a valid unsigned decimal number
atou(-0.0): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
-1
"-1" is not a valid unsigned decimal number
atou(-1): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
+0
atou(+0): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
+2
atou(+2): 2
./atou
Enter an unsigned decimal number [+]?[0-9]+
a
"a" is not a valid unsigned decimal number
atou(a): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
+
"+" is not a valid number
atou(+): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
-
"-" is not a valid number
atou(-): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
1.2
"1.2" is not a valid unsigned decimal number
atou(1.2): 1
./atou
Enter an unsigned decimal number [+]?[0-9]+
-1.2
"-1.2" is not a valid unsigned decimal number
atou(-1.2): 0
./atou
Enter an unsigned decimal number [+]?[0-9]+
65535 // USHRT_MAX (limits.h)
atou(65535): 65535
./atou
Enter an unsigned decimal number [+]?[0-9]+
4294967295 // UINT_MAX
atou(4294967295): 4294967295
./atou
Enter an unsigned decimal number [+]?[0-9]+
4294967296 // UINT_MAX+1
atou(4294967296): 0 // modulo 2 arithmetic
./atou
Enter an unsigned decimal number [+]?[0-9]+
4294967297 // UINT_MAX+2
atou(4294967297): 1 // modulo 2 arithmetic
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf(), scanf()
#define LENGTH 15 // max length of hex string (2 hex digits per byte)
int htoi(char *hex); // hex to decimal (integer)
int main()
{
char s[LENGTH];
printf("Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+\n");
scanf("%s", s);
printf("htoi(%s): %d\n", s, htoi(s));
return 0;
}
int htoi(char *hex) // hex to decimal (integer)
{
if (*hex == '\0') // empty string
{ // not a number
printf("\"%s\" is not a valid number\n", hex);
return 0; // return value does not signal error, should use an exception
}
// here hex is not empty
int n = 0, sign = 1;
char temp, *p = hex;
if (*p == '-') // negative number
{
sign = -1;
p++; // skip optional sign
}
else if (*p == '+') // positive number
{
p++; // skip optional sign
}
if (*p == '0')
{
p++;
if (*p == '\0')
{
return n; // return 0; // valid hex number
}
if (*p == 'x' || *p == 'X')
{p++;} // skip optional 0x or 0X
}
else if (*p == 'o' || *p == 'O')
{
temp = *p;
p++;
if (*p == 'x' || *p == 'X')
{
printf("\"%s\" is not a valid hex number\n", hex);
*(p-1) = '0'; // changes hex
printf("Did you mean \"%s\"?\n", hex);
*(p-1) = temp; // changes hex back, needed in main()
printf("Note the difference between 'o' or 'O' and '0' (zero)\n");
return 0;
}
}
if (*p == '\0')
{
printf("\"%s\" is not a valid hex number\n", hex);
return 0;
}
while (*p != '\0')
{
if (*p >= '0' && *p <= '9')
{n = n*16 + (*p - '0');}
else if (*p >= 'a' && *p <= 'f')
{n = n*16 + (*p-'a'+10);}
else if (*p >= 'A' && *p <= 'F')
{n = n*16 + (*p-'A'+10);}
else // not a hex number
{
printf("\"%s\" is not a valid hex number\n", hex);
return sign * n;
}
p++;
}
return sign * n;
}
/*
gcc htoi.c -o htoi
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
0
htoi(0): 0
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
0x
"0x" is not a valid hex number
htoi(0x): 0
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
1.2
"1.2" is not a valid hex number
htoi(1.2): 1
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
-2.5
"-2.5" is not a valid hex number
htoi(-2.5): -2
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
10
htoi(10): 16
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
0x9
htoi(0x9): 9
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
g
"g" is not a valid hex number
htoi(g): 0
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
-25
htoi(-25): -37
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
0x-10 // write -0x10
"0x-10" is not a valid hex number
htoi(0x-10): 0
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
-0x10
htoi(-0x10): -16
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
+025
htoi(+025): 37
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
oxc // letter 'o' instead of digit '0'
"oxc" is not a valid hex number
Did you mean "0xc"?
Note the difference between 'o' or 'O' and '0' (zero)
htoi(oxc): 0
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
0xc
htoi(0xc): 12
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
+Ox14
"+Ox14" is not a valid hex number
Did you mean "+0x14"?
Note the difference between 'o' or 'O' and '0' (zero)
htoi(+Ox14): 0
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
+0x14
htoi(+0x14): 20
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
0xa1
htoi(0xa1): 161
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
0xaA
htoi(0xaA): 170
/htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
0Xaa
htoi(0Xaa): 170
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
aA
htoi(aA): 170
./htoi
Enter a hex number [+-]?[0x]?[0-9a-f]+ or [+-]?[0X]?[0-9A-F]+
-AA
htoi(-AA): -170
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf(), scanf()
#define LENGTH 20 // max length of octal string (3 octal digits per byte)
int otoi(char *octal); // octal to decimal (integer)
int main()
{
char s[LENGTH];
printf("Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+\n");
scanf("%s", s);
printf("otoi(%s): %d\n", s, otoi(s));
return 0;
}
int otoi(char *octal) // octal to decimal (integer)
{
if (*octal == '\0') // empty string is not a number
{
printf("\"%s\" is not a valid number\n", octal);
return 0; // should handle the error with an exception as we cannot
} // signal the error here with a returned value
// here octal is not empty
int n = 0, sign = 1;
char temp, *p = octal;
if (*p == '-')
{
sign = -1;
p++; // skip optional sign
}
else if (*p == '+')
{
p++; // skip optional sign
}
if (*p == '0')
{
p++; // skip optional '0'
if (*p == '\0')
{return n;} // return 0; // valid octal number
}
else if (*p == 'o' || *p == 'O')
{
printf("\"%s\" is not a valid octal number\n", octal);
temp = *p;
*p = '0'; // change octal
printf("Did you mean \"%s\"?\n", octal);
*p = temp; // change octal back, needed in main()
printf("Note the difference between 'o' or 'O' and '0' (zero)\n");
return 0;
}
else if (*p == '\0')
{
printf("\"%s\" is not a valid octal number\n", octal);
return 0;
}
while (*p != '\0')
{
if (*p >= '0' && *p <= '7')
{n = n*8 + (*p - '0');}
else // not an octal number
{
printf("\"%s\" is not a valid octal number\n", octal);
return sign * n;
}
p++;
}
return sign * n;
}
/*
gcc otoi.c -o otoi
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
0
otoi(0): 0
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
+
"+" is not a valid octal number
otoi(+): 0
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
-
"-" is not a valid octal number
otoi(-): 0
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
1.2
"1.2" is not a valid octal number
otoi(1.2): 1
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
-2.5
"-2.5" is not a valid octal number
otoi(-2.5): -2
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
o1 // letter 'o' instead of digit '0'
"o1" is not a valid octal number
Did you mean "01"?
Note the difference between 'o' or 'O' and '0' (zero)
otoi(o1): 0
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
-o.0
"-o.0" is not a valid octal number
Did you mean "-0.0"?
Note the difference between 'o' or 'O' and '0' (zero)
otoi(-o.0): 0
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
-0.0
"-0.0" is not a valid octal number
otoi(-0.0): 0
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
22
otoi(22): 18
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
+022
otoi(+022): 18
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
+0022
otoi(+0022): 18
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
-09
"-09" is not a valid octal number
otoi(-09): 0
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
0-7 // write -07
"0-7" is not a valid octal number
otoi(0-7): 0
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
-07
otoi(-07): -7
./otoi
Enter an octal number [+-]?0[0-7]* or [+-]?[0-7]+
-7
otoi(-7): -7
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf(), scanf()
#define LENGTH 50 // max length of binary string (8 bits per byte)
int btoi(char *); // binary to decimal (integer)
int main()
{
char s[LENGTH];
printf("Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+\n");
scanf("%s", s);
printf("btoi(%s): %d\n", s, btoi(s));
return 0;
}
int btoi(char *bin) // binary to decimal (integer)
{
if (*bin == '\0') // empty string is not a number
{
printf("\"%s\" is not a valid number\n", bin);
return 0; // should handle the error with an exception as we cannot
} // signal the error here with a returned value
// here bin[] is not empty
int n = 0, sign = 1;
char temp, *p = bin;
if (*p == '-') // negative number
{
sign = -1;
p++; // skip optional sign
}
else if (*p == '+') // positive number
{
p++; // skip optional sign
}
if (*p == '0')
{
p++;
if (*p == '\0')
{return n;} // return 0; // valid binary number
if (*p == 'b' || *p == 'B')
{p++;} // skip optional 0b or 0B
}
else if (*p == 'o' || *p == 'O')
{
temp = *p;
p++;
if (*p == 'b' || *p == 'B')
{
printf("\"%s\" is not a valid binary number\n", bin);
*(p-1) = '0'; // change bin
printf("Did you mean \"%s\"?\n", bin);
*(p-1) = temp; // change bin back, needed in main()
printf("Note the difference between 'o' or 'O' and '0' (zero)\n");
return 0;
}
}
if (*p == '\0')
{ // "0b" or "0B" is not a valid binary number
printf("\"%s\" is not a valid binary number\n", bin);
return 0;
}
while (*p != '\0')
{
if (*p == '0' || *p == '1')
{n = n*2 + (*p - '0');}
else // not a binary number
{
printf("\"%s\" is not a valid binary number\n", bin);
return sign * n;
}
p++;
}
return sign * n;
}
/*
gcc btoi.c -o btoi
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
+
"+" is not a valid binary number
btoi(+): 0
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
-
"-" is not a valid binary number
btoi(-): 0
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
+01
btoi(+01): 1
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
0b
"0b" is not a valid binary number
btoi(0b): 0
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
a
"a" is not a valid binary number
btoi(a): 0
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
123
"123" is not a valid binary number
btoi(123): 1
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
-14
"-14" is not a valid binary number
btoi(-14): -1
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
ob1 // letter 'o', not digit '0'
"ob1" is not a valid binary number
Did you mean "0b1"?
Note the difference between 'o' or 'O' and '0' (zero)
btoi(ob1): 0
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
0b1
btoi(0b1): 1
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
-0b101
btoi(-0b101): -5
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
11111111
btoi(11111111): 255
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
-0B100000000
btoi(-0B100000000): -256
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
0b+1 // write +0b1
"0b+1" is not a valid binary number
btoi(0b+1): 0
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
+0b1
btoi(+0b1): 1
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
0B-11 // write -0B11
"0B-11" is not a valid binary number
btoi(0B-11): 0
./btoi
Enter a binary number [+-]?(0b)?[01]+ or [+-]?(0B)?[01]+
-0B11
btoi(-0B11): -3
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#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
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#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
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#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)
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#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
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#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
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf(), scanf()
#include <ctype.h> // for isspace(), isdigit()
#define SIZE 200 // max no of digits before and after decimal point
double atof(char *); // string to double
int main()
{
char fpn[SIZE]; // floating-point number
// valid fpn: 0, +0, -0, 0.0, -0.0, +0., 0., .0, -.0, +.0
printf("Type a floating-point decimal number "
"(at least 1 digit) [+-]?[0-9]*[.]?[0-9]*\n");
scanf("%s", fpn);
printf("%f\n", atof(fpn));
return 0;
}
double atof(char *s) // string to double
{
double val, power;
int sign;
char *p;
for (p = s; isspace(*p); p++)
{} // skip whitespace
sign = (*p == '-') ? -1 : 1;
if (*p == '+' || *p == '-')
{p++;}
if ((*p == '\0') || (*p == '.' && *(p+1) == '\0'))
{
printf("\"%s\" is not a valid floating-point decimal number\n", s);
return 0.0; // should signal the error with an exception
}
for (val = 0.0; isdigit(*p); p++)
{ // ending '\0' of s[] is not a digit
val = 10.0 * val + (*p - '0');
}
if (*p == '.') // optional decimal point
{p++;} // skip decimal point, move to fractional part
for (power = 1.0; isdigit(*p); p++)
{
val = 10.0 * val + (*p - '0');
power *= 10.0; // power = power * 10.0;
}
return sign * val / power;
}
/*
gcc atof.c -o atof
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
.
"." is not a valid floating-point decimal number
0.000000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
+
"+" is not a valid floating-point decimal number
0.000000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
-
"-" is not a valid floating-point decimal number
0.000000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
+.
"+." is not a valid floating-point decimal number
0.000000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
-.
"-." is not a valid floating-point decimal number
0.000000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
+0.2
0.200000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
-.5
-0.500000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
12.35
12.350000
/atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
0xa0 // we said decimal
0.000000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
-2a1.23 // stops at non-decimal 'a'
-2.000000
./atof
Type a floating-point decimal number (at least 1 digit) [+-]?[0-9]*[.]?[0-9]*
-123.12a3 // stops at non-decimal 'a'
-123.120000
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf(), scanf()
#include <ctype.h> // for isspace(), isdigit()
#define SIZE 200 // max no of digits before and after decimal point
double atof(char *); // string to double, optional scientific notation
int main()
{
char fpn[SIZE]; // floating-point number
double d;
// valid fpn: 0, +0, -0, 0.0, -0.0, +0., 0., .0, -.0, +.0
printf("Type a floating-point decimal number (at least 1 digit), followed by \n");
printf("an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?\n");
scanf("%s", fpn);
d = atof(fpn);
printf("%f\n", d);
printf("%g\n", d);
return 0;
}
double atof(char *s) // string to double, optional scientific notation
{
double val, power;
int sign, exponent, expsign;
char *p;
for (p = s; isspace(*p); p++)
{} // skip whitespace
sign = (*p == '-') ? -1 : 1;
if (*p == '+' || *p == '-')
{p++;}
if ((*p == '\0') || (*p == '.' && *(p+1) == '\0'))
{
printf("\"%s\" is not a valid floating-point decimal number\n", s);
return 0.0; // should signal the error with an exception
}
for (val = 0.0; isdigit(*p); p++)
{ // ending '\0' of s[] is not a digit
val = 10.0 * val + (*p - '0');
}
if (*p == '.') // optional decimal point
{p++;} // skip decimal point, move to fractional part
for (power = 1.0; isdigit(*p); p++)
{
val = 10.0 * val + (*p - '0');
power *= 10.0; // power = power * 10.0;
}
if (*p == 'e' || *p == 'E') // optional exponent
{p++;} // skip 'e' or 'E', move to (signed) exponent
else {return sign * val / power;} // no exponent
// here there is an exponent
expsign = (*p == '-') ? -1 : 1;
if (*p == '+' || *p == '-')
{p++;} // skip sign, move to exponent
if (*p == '\0')
{
printf("\"%s\" is not a valid floating-point decimal number\n", s);
return 0.0; // should signal the error with an exception
}
for (exponent = 0; isdigit(*p); p++)
{ // ending '\0' of s is not a digit
exponent = 10 * exponent + (*p - '0');
}
while (exponent > 0) // while(exponent)
{
if (expsign < 0)
{power *= 10.0;} // we divide by power to find the return value
else {power /= 10.0;}
exponent--;
}
return sign * val / power;
}
/*
gcc atog.c -o atog
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
.
"." is not a valid floating-point decimal number
0.000000
0
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
+
"+" is not a valid floating-point decimal number
0.000000
0
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
-
"-" is not a valid floating-point decimal number
0.000000
0
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
+.
"+." is not a valid floating-point decimal number
0.000000
0
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
-.
"-." is not a valid floating-point decimal number
0.000000
0
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
+0.2
0.200000
0.2
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
-.5
-0.500000
-0.5
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
-2a1.23 // stops at non-decimal 'a'
-2.000000
-2
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
0.2e
"0.2e" is not a valid floating-point decimal number
0.000000
0
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
+2.3e+
"+2.3e+" is not a valid floating-point decimal number
0.000000
0
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45e-6
0.000123
0.00012345
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45E+6
123450000.000000
1.2345e+08
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45e6
123450000.000000
1.2345e+08
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45e12
123449999999999.968750
1.2345e+14
./atog
Type a floating-point decimal number (at least 1 digit), followed by
an optional scientific notation, [+-]?[0-9]*[.]?[0-9]*([eE][+-]?[0-9]+)?
123.45e-25
0.000000
1.2345e-23
*/