Exercise 5-1. As written, getint() treats a + or - not followed by a digit as a valid representation of zero. Fix it to push such a character back on the input.
-123 254 120356 145879 +56 +963 -89 78 3254 -852
0123 142587 -8526 45678 231054 52368 +0236 789 2 0
#include <stdio.h> // for getchar(), putchar(), printf(), EOF
#define SIZE 100 // array size
int getint(int *); // get the next int from input
int main()
{
int i, n, array[SIZE];
for (n = 0; n < SIZE; n++)
{
i = getint(&array[n]);
if (i == EOF || i == 0) // end of input or not a number
{break;} // out of for()
}
printf("Array size: %d\n", n);
for (i = 0; i < n; i++) // print array
{printf("%d%c", array[i], (i % 10) == 9 ? '\n' : ' ');}
if (n % 10 != 0) {putchar('\n');}
return 0;
}
#include <ctype.h> // for isspace(), isdigit()
int getch(void);
void ungetch(int);
int getint(int *pn) // get the next int from input
{
int c, sign;
while (isspace(c = getch())) // skip whitespace
{}
if (c == EOF)
{return c;} // return EOF;
if (!isdigit(c) && c != '+' && c != '-')
{
ungetch(c);
return 0; // not a number
}
sign = (c == '-') ? -1 : 1;
if (c == '+' || c == '-')
{c = getch();}
if (!isdigit(c))
{
ungetch(c);
return 0; // not a number
}
for (*pn = 0; isdigit(c); c = getch())
{
*pn = 10 * *pn + (c - '0');
}
*pn *= sign;
ungetch(c); // if (c == EOF), it will be returned by the next call to getint()
return 1; // valid integer found
}
// buffer for ungetch():
int buf = EOF-1; // not a real character, not even EOF
int getch(void) // get a (possibly pushed-back) character
{
if (buf < EOF)
{
return getchar();
}
int temp = buf; // buf >= EOF
buf = EOF-1; // reset buf
return temp;
}
// push character back on input (make it available for the next getch()):
void ungetch(int c)
{
buf = c;
}
/*
gcc getint.c -o getint
./getint
a
Array size: 0
./getint
a 1
Array size: 0
./getint
1 a
Array size: 1
1
./getint
-.2
Array size: 0
./getint
1.2
Array size: 1
1
./getint
0 // Type Enter, then Ctrl^D in Linux or Ctrl^Z + Enter in Windows (EOF)
Array size: 1
0
./getint
-1 +02
Array size: 2
-1 2
./getint
0 1 2 3 4 5 6 7 8 9
Array size: 10
0 1 2 3 4 5 6 7 8 9
./getint
0 1 2 3 4 5 6 7 8 9 10
Array size: 11
0 1 2 3 4 5 6 7 8 9
10
./getint < integers.txt
Array size: 20
-123 254 120356 145879 56 963 -89 78 3254 -852
123 142587 -8526 45678 231054 52368 236 789 2 0
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
Exercise 5-2. Write getfloat(), the floating-point analog of getint(). What type does getfloat() return as its function value?
-123 254 120356 145879 +56 +963 -89 78 3254 -852
0123 142587 -8526 45678 231054 52368 +0236 789 2 0
-.2 +.3 -1 +02.3 12365 0 -0.2 +0 -9927 -0
-123456789 123456789
#include <stdio.h> // for getchar(), putchar(), printf(), EOF
#define SIZE 100 // array size
int getfloat(float *); // get the next float from input
int main()
{
int i, n;
float array[SIZE];
for (n = 0; n < SIZE; n++)
{
i = getfloat(&array[n]);
if (i == EOF || i == 0) // end of input or not a number
{break;} // out of for()
}
printf("Array size: %d\n", n);
for (i = 0; i < n; i++) // print array
{printf("%g%c", array[i], (i % 10) == 9 ? '\n' : ' ');}
if (n % 10 != 0) {putchar('\n');}
return 0;
}
#include <ctype.h> // for isspace(), isdigit()
int getch(void);
void ungetch(int);
int getfloat(float *pn) // get the next float from input
{
int c, sign;
int digits = 0; // no of digits > 0 for a valid number
float power;
while (isspace(c = getch())) // skip whitespace
{}
if (c == EOF)
{return c;} // return EOF;
if (!isdigit(c) && c != '+' && c != '-' && c != '.')
{
ungetch(c);
return 0; // not a number
}
sign = (c == '-') ? -1 : 1;
if (c == '+' || c == '-')
{c = getch();}
if (!isdigit(c) && c != '.')
{
ungetch(c);
return 0; // not a number
}
for (*pn = 0; isdigit(c); c = getch()) // get integer part
{
digits++;
*pn = 10 * *pn + (c - '0');
}
if (c == '.')
{c = getch();}
for (power = 1.0; isdigit(c); c = getch()) // get fractional part
{
digits++;
*pn = 10 * *pn + (c - '0');
power *= 10.0;
}
*pn *= sign;
*pn /= power;
ungetch(c); // if (c == EOF), it will be returned by the next call to getfloat()
if (digits == 0) // not a valid number, like `+', `-', `.', `-.', `+.'
{return 0;}
return 1; // valid float found
}
// buffer for ungetch():
int buf = EOF-1; // not a real character, not even EOF
int getch(void) // get a (possibly pushed-back) character
{
if (buf < EOF)
{
return getchar();
}
int temp = buf; // buf >= EOF
buf = EOF-1; // reset buf
return temp;
}
// push character back on input (make it available for the next getch()):
void ungetch(int c)
{
buf = c;
}
/*
gcc getfloat.c -o getfloat
./getfloat
a
Array size: 0
./getfloat
a 1
Array size: 0
./getfloat
+.
Array size: 0
./getfloat
1 a
Array size: 1
1
./getfloat
-.2 // Type Enter, then Ctrl^D in Linux or Ctrl^Z + Enter in Windows (EOF)
Array size: 1
-0.2
./getfloat
-.0
Array size: 1
-0
./getfloat
1.2
Array size: 1
1.2
./getfloat
0
Array size: 1
0
./getfloat
-1 +02
Array size: 2
-1 2
./getfloat
0 1 2 3 4 5 6 7 8 9
Array size: 10
0 1 2 3 4 5 6 7 8 9
./getfloat
0 1 2 3 4 5 6 7 8 9 10
Array size: 11
0 1 2 3 4 5 6 7 8 9
10
./getfloat < integers.txt
Array size: 20
-123 254 120356 145879 56 963 -89 78 3254 -852
123 142587 -8526 45678 231054 52368 236 789 2 0
./getfloat < floats.txt
Array size: 12
-0.2 0.3 -1 2.3 12365 0 -0.2 0 -9927 -0
-1.23457e+08 1.23457e+08
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for printf(), putchar()
int main()
{
char p[10];
char c = p[-1];
printf("c = %c\n", c);
printf("&c = %p\n", &c);
printf("&p = %p\n", &p);
printf("p = %s\n", p);
// p++; // illegal // compile error (constant pointer)
char *cp = p;
cp++; // legal
cp[-2] = 'A'; // p[-1]
cp[-1] = 'B'; // p[0]
printf("p = %s\n", p);
c = p[-1];
printf("c = %c\n", c);
printf("&c = %p\n", &c);
printf("p-cp = %ld\n", p-cp);
printf("&cp = %p\n", &cp);
cp = 0;
printf("p-cp = %ld\n", p-cp);
printf("&cp = %p\n", &cp);
void *v = cp;
printf("v-cp = %ld\n", v-(void*)cp);
printf("v-cp = %ld\n", (char*)v-cp);
printf("&v = %p\n", &v);
int i;
for (i = 1; i <= 10; i++)
{
printf("p[-%d] = %c, ", i, p[-i]); // *(p-i)
}
putchar('\n');
for (i = 1; i <= 5; i++)
{
printf("&p[-%d] = %p, ", i, p-i); // &p[-i]
}
putchar('\n');
char *pm = "now is the time"; // pointer to message
printf("pm = %s\n", pm);
// pm[0] = 'l'; // runtime error (segmentation fault)
char cm[] = "now is the time"; // a message
// pm[0] = 'l'; // runtime error (segmentation fault)
pm = cm;
pm[0] = 'l';
printf("pm = %s\n", pm);
}
/*
gcc pointers.c -o pointers
./pointers
c =
&c = 0x7ffc82999cf3
&p = 0x7ffc82999d16
p =
p = B
c = A
&c = 0x7ffc82999cf3
p-cp = -1
&cp = 0x7ffc82999cf8
p-cp = 140722499591446
&cp = 0x7ffc82999cf8
v-cp = 0
v-cp = 0
&v = 0x7ffc82999d00
p[-1] = A, p[-2] = v, p[-3] = &, p[-4] = �, p[-5] = �, p[-6] = �, p[-7] = , p[-8] = , p[-9] = U, p[-10] = �,
&p[-1] = 0x7ffc82999d15, &p[-2] = 0x7ffc82999d14, &p[-3] = 0x7ffc82999d13, &p[-4] = 0x7ffc82999d12, &p[-5] = 0x7ffc82999d11,
pm = now is the time
pm = low is the time
*/