[comp.lang.c] #include <is.h>

matthew@sunpix.UUCP ( Sun NCAA) (12/21/88)

I'm only a beginner 'C' programmer, but for a recent technical college midterm
exam, I had to write a program that would read in strings from the keyboard,
detect if they contained valid floating point numbers, count the total number
of entries, the total number of valid floating point entries and as output
print the count of the total number of entries, the total number of valid 
entries and the average of the total valid entries and a decending sorted list
of valid entries.

All this was quite simple, and of course I used gets(); to get the an input
string and atof(); to do the string to float conversion. But no where could
I find a function to validate the string to see if it did contain a number
that atof(); would correctly interpret (0.0 is a valid floating point number
and I did to be able to enter it). After studying 'atof();' in K & R,
I put this together. It so easy, I wonder why I haven't seen it before.

[BTW, isfloat(); can double for isdouble(); as can isint(); for islong();]


	int isfloat(str)
	
	int	isspace(char);
	int	isdigit(char);
	char	str[];
	
	{
		int	i;
	
		for ( i = 0; isspace(str[i]); i++)
			;						/* eliminate leading whitespace    */
		if (str[i] == '+' || str[i] == '-')
			i++;					/* if '+' or '-' skip to next char */
		if (str[i] == '.')
			i++;					/* if '.' skip to next char        */
		if (isdigit(str[i]))
			return(1);				/* if digit, return 'true'         */
		return(0);					/* not a float, return 'false'     */
	}
	
	int isint(str) 
	 
	int     isspace(char);
	int     isdigit(char);
	char    str[];
	 
	{ 
	        int     i; 
	 
	        for ( i = 0; isspace(str[i]); i++)
	                ;				/* eliminate leading whitespace    */
	        if (str[i] == '+' || str[i] == '-')
	                i++;			/* if '+' or '-' skip to next char */
	        if (isdigit(str[i]))
	                return(1);		/* if digit, return 'true'         */
	        return(0);				/* not a int, return 'false'       */
	}
	
-- 
Matthew Lee Stier     (919) 469-8300|
Sun Microsystems ---  RTP, NC  27560|          "Wisconsin   Escapee"
uucp: {sun, rti}!sunpix!matthew     |

nagel@blanche.ics.uci.edu (Mark Nagel) (12/21/88)

In article <354@greens.UUCP>, matthew@sunpix ( Sun NCAA) writes:
|
|[BTW, isfloat(); can double for isdouble(); as can isint(); for islong();]
|
| [code deleted]

Gosh, a lexical analyzer -- wish I'd thought of it :-).  Seriously,
though, it would be nice to have something like this be part of the
standard C library so that one could check validity of things like
atoi, etc.

Mark Nagel @ UC Irvine, Dept of Info and Comp Sci
ARPA: nagel@ics.uci.edu              | The world is coming to an end.
UUCP: {sdcsvax,ucbvax}!ucivax!nagel  | Please log off.

karl@haddock.ima.isc.com (Karl Heuer) (12/21/88)

In article <1920@paris.ics.uci.edu> nagel@blanche.ics.uci.edu (Mark Nagel) writes:
>... it would be nice to have something like this be part of the standard C
>library so that one could check validity of things like atoi, etc.

"Something like it" *is* in the Standard C library.  Check strtod() (for
floating point) and strtol() (for integer); each scans and evaluates its
string, and returns enough information to distinguish failure from valid
return values.

Btw, the posted version of the function accepts "3.14xyz" as valid (as does
atof() itself).  I would think that the problem as stated should require that
string to be rejected.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

henry@utzoo.uucp (Henry Spencer) (12/22/88)

In article <354@greens.UUCP> matthew@sunpix.UUCP ( Sun NCAA) writes:
>...and atof(); to do the string to float conversion. But no where could
>I find a function to validate the string to see if it did contain a number
>that atof(); would correctly interpret...

Some existing C implementations, and all future ANSI-conforming ones, have
a "strtod" function (and a "strtol" counterpart) that does atof's job but
gives you hooks to find out whether it worked and how much of the string
it used up.
-- 
"God willing, we will return." |     Henry Spencer at U of Toronto Zoology
-Eugene Cernan, the Moon, 1972 | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

wietse@wzv.UUCP (Wietse Z. Venema) (12/22/88)

In article <354@greens.UUCP> matthew@sunpix.UUCP ( Sun NCAA) writes:
>                                                         But no where could
>I find a function to validate the string to see if it did contain a number
>that atof(); would correctly interpret.
>...
>[BTW, isfloat(); can double for isdouble(); as can isint(); for islong();]
>

int isfloat(s)	/* wants a null-terminated string with f.p. number */
char *s;
{
	char junk = 0;
	float fval;

	return (sscanf(s,"%f%c",&fval,&junk) == 1);
}

Of course, you will want to keep the result of the string-to-float
conversion.
-- 
work:	wswietse@eutrc3.uucp	| Eindhoven University of Technology
work:	wswietse@heitue5.bitnet	| Mathematics and Computing Science
home:	wietse@wzv.uucp		| 5600 MB Eindhoven, The Netherlands

guy@auspex.UUCP (Guy Harris) (12/22/88)

>Btw, the posted version of the function accepts "3.14xyz" as valid (as does
>atof() itself).  I would think that the problem as stated should require that
>string to be rejected.

Also note that "strtod" can be used in code that would reject this
string.  It stops scanning at the first unrecognized character; for
instance, if the floating-point number is expected to be terminated by a
white-space character or by a '\0' (i.e., it's expected to be a token in
a string, with tokens delimited by white space), the caller of "strtod"
would pass it a non-NULL second argument that pointed to a "char *"
variable initialized to point to the string; if, after calling "strtod",
the "char *" variable still pointed to the string, or pointed to a
character that wasn't white space or '\0', the string should be rejected.

ark@alice.UUCP (Andrew Koenig) (12/23/88)

In article <175@wzv.UUCP>, wietse@wzv.UUCP (Wietse Z. Venema) writes:
 
> int isfloat(s)	/* wants a null-terminated string with f.p. number */
> char *s;
> {
> 	char junk = 0;
> 	float fval;

> 	return (sscanf(s,"%f%c",&fval,&junk) == 1);
> }

Nope, this one doesn't work either.

Give it something like "1e500" and it dumps core
due to a floating-point overflow.

-- 
				--Andrew Koenig
				  ark@europa.att.com

matthew@sunpix.UUCP ( Sun NCAA) (12/24/88)

In article <11252@haddock.ima.isc.com>, karl@haddock (Karl Heuer) writes:
> 
> Btw, the posted version of the function accepts "3.14xyz" as valid (as does
> atof() itself).  I would think that the problem as stated should require that
> string to be rejected.
> 
> Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint


Now that strtol() && strtod() have been pointed out to me, I've had a chance to
look them over. Thanks all.  As for the problem I stated, Any number acceptable
to atof(), and would produce a valid number output, was acceptable. I devised
isfloat() && isint() to test for atof() && atoi() acceptablity ( I wrote them
so that I was sure that if atof() did return a 0.0, that it was indeed a value
of 0.0).  Also, the class is using an older compiler, which does not support 
strtol() && strtod(), so could not have been used in my problem in the first
place.


-- 
Matthew Lee Stier     (919) 469-8300|
Sun Microsystems ---  RTP, NC  27560|          "Wisconsin   Escapee"
uucp: {sun, rti}!sunpix!matthew     |

gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/27/88)

In article <1920@paris.ics.uci.edu> nagel@blanche.ics.uci.edu (Mark Nagel) writes:
-... it would be nice to have something like this be part of the
-standard C library so that one could check validity of things like
-atoi, etc.

You can use sscanf() to validate input format.