TO C OR NOT TO *C

Michael Condict condict at cs.vu.nl
Mon Oct 23 19:36:06 AEST 1989


In article <991 at cirrusl.UUCP> dhesi%cirrusl at oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
>In article <1989Oct16.172249.18387 at utzoo.uucp> henry at utzoo.uucp (Henry
>Spencer) writes:
>>Unless you have reason to be *absolutely certain* that end-of-file will
>>not occur when attempting to read that character, the result of getc should
>>*never* be assigned to a char without first testing to see if it is equal
>>to EOF. 
>
>Playing Devil's advocate, we bravely yet blithely break Henry Spencer's
>every rule:
>
>     char c;
>
>     c = getc(stdin);           /* Oops! forgot to test for EOF! */
>     do {
>        if feof(stdin)
>           break;               /* WHEW! */
>        .. do stuff with c ..
>        c = getc(stdin);
>     } while (1);

It is clear that this is a safe way to assign the result of getc to a char,
but why write it in such a distorted way?  Much simpler is:

	c = getc(stdin);
	while (!feof(stdin)) {
		.. do stuff with c ..
		c = getc(stdin);
	}

But this does points out the main disadvantage of the use of an eof predicate
over the use of in in-band EOF value:  As in Pascal, the natural way to
write every input loop is:

	Arbitrarily_complicated_stuff_that_does_some_input
	while (! feof(stdin)) {
		.. do stuff with input ..
		Arbitrarily_complicated_stuff_that_does_some_input
	}

You have to write two copies of the code that gets input, a maintainence
headache.  Of course, you can put this code in a function and write the
function call twice, but this can seem silly it it is just two lines of code.

This problem can be gotten around in C, using the ',' operator:

	while (c = getc(stdin), !feof(stdin)) {
		.. do stuff with c ..
	}

but there is no way around it in Pascal.

Michael Condict
Vrije University
Amsterdam



More information about the Comp.lang.c mailing list