Exercise 5-6-2 (conversions - String to decimal)
Chapter_5 Exercise_5-6 Exercise_5-6-1 | Exercise_5-6-3 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: atoi.c atou.c atof.c atog.c
atoi.c K&R, p. 43 (ch2-atoi) download
#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)
*/
atou.c (ch2-atou) download
#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
*/
atof.c K&R, p. 71 (ch4-atof) download
#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
*/
atog.c K&R, p. 73 (Ex_4-2) download
#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
*/
Chapter_5 Exercise_5-6 Exercise_5-6-1 | BACK_TO_TOP | Exercise_5-6-3 Exercise_5-7 |
Comments
Post a Comment