Write getfloat, the floating-point analog of getint. What type does getfloat return as its function value?
In direct answer to the question, I think getfloat
should also return an int
(same as getint
).
The value getfloat
returns won't be meaningful, just as a way to capture EOF
, so I have modified it to always return 0
unless it finds EOF
.
I tried to stay within the getint
style of program structure, but didn't find any way that I found worked. Decided to restructure the function to something that makes sense to me.
- loop over each input character until found something we want to process
- if found EOF return from function early
- loop over each input character until we are happy that we have a valid chunk of input
- convert chunk of input to a float using
atof
fromstdlib.h
as shown in previous Reverse Polish Calculator exercises - put float in array
Carried over idea from previous exercise so that getfloat
does not consider '+'
or '-'
as a 0
Also, included that getfloat
can now discard random input characters (as I have shown in output section), which was bugging me
Seems I missed some of the instructions:
Our version of getint returns EOF for end of file zero if the next input is not a number, and a positive value if the input contains a valid number.
So I guess this means the calling function, which in this case is main
should also check for the return value getfloat
being a zero, which makes sense
Looking at solution by zer0325 (youtube, github),
I can see how you can do the char
digits to float
conversion by storing the fractional part in a new variable and dividing it at the end
I won't rewrite my solution, as it works, but it is good to know a way to write it without another external library and probably the way it was intended to be written by the authors.
#include <stdio.h>
#include <ctype.h> /* for isspace(), isdigit() */
#include <stdlib.h> /* for atof() */
#define SIZE 6
int getfloat(double *);
int main()
{
int n, getfloat(double *);
double array[SIZE];
for (n = 0; n < SIZE && getfloat(&array[n]) != EOF; n++)
;
for (int i = 0; i < SIZE; i++)
printf("%d: %.3f\n", i, array[i]);
}
int getch(void);
void ungetch(int);
#define MAXNUM 100
int getfloat(double *pn)
{
int i = 0, c;
char s[MAXNUM];
int found = 0;
while(!found) /* input validation loop */
{
s[0] = c = getch(); /* get next input character */
if (isdigit(c)) { /* found digit */
found = 1;
}
else if (c == '-') { /* found '-' */
if(isdigit(c = getch())) { /* is next char digit */
s[i = 1] = c;
found = 1;
} else {
ungetch(c);
}
}
else if (c == EOF) { /* found end of file */
found = 1;
}
}
if (c == EOF) /* exit early */
return c;
while (isdigit(s[++i] = c = getch())) /* collect integer part */
;
if (c == '.')
while (isdigit(s[++i] = c = getch())) /* collect fraction part */
;
s[i] = '\0';
*pn = atof(s);
ungetch(c);
return 0;
}
#define BUFSIZE 100
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */
int getch(void) /* get a (possibly pushed back) character */
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c) /* push character back on input */
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}