Kartheek Tammana
Kartheek Tammana

Reputation: 80

EOF not detected by C on Raspberry Pi

So I was writing a program on my Raspberry Pi Zero to count the frequencies of different word lengths in the input, but the program didn't stop at EOF.

So I tried this to debug:

#include <stdio.h>
#include <stdlib.h>

void main() {
    char c;
    while ( (c = getchar()) != EOF) {
        putchar(c);
    }
}

And compiled with this:

gcc test.c && ./a.out <input.txt

It printed out the input text, but then just kept printing question marks until I hit Ctrl+C. When I copied the program over onto my laptop and ran it there, everything worked fine.

I could just finish on the laptop, but I'm curious. Why can't the Pi detect when the file hit EOF?

Upvotes: 3

Views: 326

Answers (3)

Some programmer dude
Some programmer dude

Reputation: 409176

First couple of facts:

  • The symbol EOF is a macro that expands to the integer constant -1. This integer constant will have the type int.
  • It's implementation-defined if char is signed or unsigned. The same compiler on different platforms might have different char implementations.

Now for the long explanation about your problem:

When integer types of different sizes are used in arithmetic expressions (and comparison is considered an arithmetic operator), then both operands of the expression undergoes usual arithmetic conversion to get a common type (usually int).

For smaller integer types, like for example char, that involves integer promotion to convert it to an int. For this promotion the value of the char needs to be kept intact, so e.g. -1 as a char will still be -1 as an int.

Because of how negative numbers are represented on most systems, the char value of -1 is (in hexadecimal) 0xff. For a signed char, when -1 is converted to an int, it keeps the value -1 (which will be represented as 0xffffffff for a 32-bit int type).

The problem comes when char is unsigned, because then when getchar returns EOF (the value -1) the unsigned char value will be equal to 255 (the unsigned decimal representation of 0xff). And when promoted to an int the value will still be 255. And 255 != -1!

That's why the getchar return type is int and not char. And one of the reason why all character-handling functions are using int instead of char.

So to solve your problem, you need to change the type of the variable c to int:

int c;

Then it will work

Upvotes: 4

alinsoar
alinsoar

Reputation: 15793

getchar's return value is supposed to be able to return any ASCII (and extended ASCII) character between 0 and 255.

In order to make the distinction between an ascii and EOF, EOF cannot be a value in this interval, so getchar's return type must have more than 8 bits.

   int getchar(void);

So you should write

int c;
while ( (c = getchar()) != EOF) ...

Upvotes: 1

Artur
Artur

Reputation: 7257

getchar returns int value not char value. Since you need some way to recognise in one getchar function if you read regular character or if function tells you there is nothing more to read - someone long time ago decided to use int so that some value bigger than char can be returned to indicate end of file. Change char to int.

Upvotes: 2

Related Questions