6

Just a little confusion I'm hoping someone can clear up - this question asks: "Our getch and ungetch do not handle a pushed-back EOF correctly. Decide what their properties ought to be if an EOF is pushed back, then implement your design".

With the code as it is, an EOF is pushed back, refetched with getch(), which causes a loop such as:

while ((c = getch()) != EOF)
    putchar(c);

to terminate when it is encountered from the buffer. I fail to see how this behaviour is incorrect. Surely as an EOF will in theory (mostly) only ever be encountered once, if it is pushed back and then read from a buffer in this way, it doesn't really matter? I hope someone could clear up the purpose of this question for me - I get that most solutions involve programming ungetch() to ignore EOF, I just don't see the point.

I'm sure there is one, as Dennis Ritchie and Brian Kernighan are a lot brighter than little old me - just hoping someone could point it out. Thanks :-)

Regards, Phil

PhilPotter1987
  • 1,306
  • 2
  • 12
  • 20

1 Answers1

5

The definition of buf is char buf[BUFSIZE]; ,according to the content in the book, page 19:

We must declare c to be a type big enough to hold any value that getchar returns. We can't use char since c must be big enough to hold EOF in addition to any possible char. Therefore we use int.

Then we get the answer:

int buf[BUFSIZE];
prehistoricpenguin
  • 6,130
  • 3
  • 25
  • 42
  • Exactly. EOF is not a character. –  Sep 16 '13 at 03:30
  • @Tsukuyo Yes, it's a value to distinguish from character. – prehistoricpenguin Sep 16 '13 at 04:26
  • I did think of this, but thought nothing of it - I assume cygwin (my current environment) uses signed chars as I was able to store an EOF value (-1) in the buffer and retrieve it just fine? – PhilPotter1987 Sep 16 '13 at 06:57
  • @PhilPotter1987 The definition of getchar is `int getchar ( void );`,the return value is `int`,and on common system, the value of `EOF` is `(int)-1`. – prehistoricpenguin Sep 16 '13 at 07:12
  • 1
    Ok - I think the reason I was experiencing the correct behaviour without problems is that GCC uses signed chars by default, so truncating an (int)-1 to a (char)-1 happens correctly. This behaviour is machine dependent though so I will use the modification you have suggested. Thanks :-) – PhilPotter1987 Sep 16 '13 at 08:22
  • Glad to here that, I suggest reading `Computer Systems: A Programmer's Perspective ` when you finish the K&R c bible. – prehistoricpenguin Sep 16 '13 at 08:54
  • Note that `getchar()` and all its friends and family are defined to return either an integer value that will fit into an `unsigned char`, OR `EOF`, so regardless of whether `char` is signed or unsigned, the only negative value `getchar()` may ever return is EOF. It's possible to miss this significant point because conversion between signed and unsigned is well-defined, but the instant you store the return value into a `char` (or into an `unsigned char`), you lose the ability to distinguish between EOF and some valid value. – This isn't my real name Sep 17 '13 at 22:42
  • 1
    So if you're doing `while ((c = getch()) != EOF)` and `c` is a `char`, then your loop will incorrectly terminate if your code reads a `\xff` character, because it'll mistake it for an EOF. – This isn't my real name Sep 17 '13 at 22:42
  • @ElchononEdelson Yes, when `truncating` happened, we lost the important information in high bits. – prehistoricpenguin Sep 18 '13 at 01:29