Re: ANSI C Challenge on readint

From: August Derleth (see_at_sig.now)
Date: 04/27/04


Date: Mon, 26 Apr 2004 22:41:36 -0600

On Mon, 26 Apr 2004 22:36:58 +0000, RoSsIaCrIiLoIA wrote:

> I a poor beginner defy this NG to write an ANSI-C portable
> int readint(FILE* fp);
> better of my in the treatment of a stream

A laudable goal for a beginning C programmer.

>
> #define P printf
> #define R return
> #define W while
> #define F for

What. The. ***. Nobody in their right mind defines macros for stuff like
this. If you can't type out 'for', you'll never make it as a programmer.

> #define is_digit(x) ('0'<=(x) && (x)<='9')

Don't define a macro to do a standard subroutine's job. (Hint: isdigit()).

> #define mult10(x) ( ((x)<<3) + ((x)<<1) )

Trust the compiler to optimize this for you, if it needs to be optimized
at all. Doing things like this makes you look stupid. It does not impress
experienced coders and it does not make you an uber-leet h4x0r.

[snip]

Ye gods, what did I do to deserve this pile of garbage in my newsreader?

>
>
>
> /* it gets an integer from fp; it is allowed this input
> * [' \t'] {'+'} or {'-'} ['0123456789']
> * range=( -INT_MAX, INT_MAX )
> * on error it returns INT_MAX (number too big or not good input)
> * or -INT_MAX (a negative number too big).

You've thought through the intent well enough to make a pretty good
comment block, but what if you actually happen to read the textual
representation of INT_MAX? How do we differentiate the error codes from a
possibly valid output?

> *
> * Bug: When it is met a not-number preceded from '+' or '-'
> * => '+' or '-' is popped from stream (if I use 2 times ungetc =>
> * Standard say i can use safety it one time only *or* it not could
> * be possible preserve the state of stream for the use of scanf,
> * getc, fgetc ...)
> * Examples:
> * fp="+a+bbb" -> readint(fp)=INT_MAX, fp="a+bbb"
> * fp="++aabbb" -> readint(fp)=INT_MAX, fp="+aabbb"
> *fp="+999999999999999999999999999+9" -> readint(fp)=INT_MAX, fp="+9"
> *fp="-999999999999999999999999999+9" -> readint(fp)=-INT_MAX, fp="+9"
> * fp="+EOF" -> readint(fp)=INT_MAX, fp="EOF"
> * fp="add" -> readint(fp)=INT_MAX, fp="add"
> * fp="+8989s"-> readint(fp)=8989 , fp="s"
> */

The examples aren't needed. Everyone knows how atoi() should behave.

>
> int readint(FILE* fp)
> {int c, sign = +1;

+1? Just say 1. Give some credit to the programmer's intelligence.

> unsigned n;

You wouldn't need to make n an unsigned if you'd stop trying to
out-optimize your own compiler. Just a hint.

[snip rest of atoi()]

Ugly, ugly code, made worse by massive macro abuse.

-- 
yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
To email me, rot13 and convert spelled-out numbers to numeric form.
"Makes hackers smile" makes hackers smile.