Harsh Vardhan
Harsh Vardhan

Reputation: 209

When my program reads CTRL-D from standard input on Linux, why does it not convert to EOF?

Below is the program that I wrote.

/*******************************************************************************
 * This program reads EOF from standard input stream to store in an integer 
 * variable and in a character variable. Both values are then output to see the
 * stored value as integer.
*******************************************************************************/
#include<stdio.h>

int main (void)
{
    /* Local Declarations */
    int        num;
    char       ch;

    /* Read EOF as character & integer and display values stored */
    printf("\nPlease only input EOF for all input prompts below");
    printf("\nNumber? ");
    scanf("%d", &num);
    printf("\nThat integer input converts to %d", num);
    printf("\nCharacter? ");
    scanf(" %c", &ch);
    printf("\nThat character input converts to %d", ch);

    /* Check if any of the stored values are recognized as EOF */
    if(num == EOF)
        printf("\nNumber is an EOF");
    if(ch == EOF)
        printf("\nCharacter is an EOF");

    /* Exit Program */
    printf("\n");
    return 0;
}// main()

I compiled using gcc on Ubuntu 11.10. It does not recognize Ctrl-D for EOF in the program and outputs 0 when trying to print its value. The output for the above program on my terminal is below.

Please only input EOF for all input prompts below
Number? 
That integer input converts to 0
Character? 
That character input converts to 0

NOTE: CTRL-D is not echoed by the terminal when I press it for the two inputs, hence not visible in the above program execution.

I have read that EOF is defined as an integer in stdio.h and stdlib.h and is traditionally defined as -1. Also, I understand that Ctrl-D simulates EOF for standard input. Then why does it not translate to -1 when storing it to an integer variable?

Upvotes: 0

Views: 4178

Answers (2)

paxdiablo
paxdiablo

Reputation: 881623

Because scanf("%d") will attempt to read characters representing a number and then store that into the given variable.

It does not store EOF into the number if you close the stream. Otherwise how would you tell the difference between end of file and entering the numeric value of EOF (-1).

The scanf will return the number of items scanned (which will be zero if format was wrong, or EOF if the stream closed or certain errors occurred). It returns this as the return code from the scanf function, not via the pointer variable you passed to it.

You should only assume the variables (that you pass in the addresses for) are populated if the return value from scanf tells you so.

In other words, you're looking for something like:

int rc = scanf ("%d", &num);
switch (rc) {
    case EOF: {
        printf ("EOF returned\n");
        break;
    }
    case 0: {
        printf ("No items scanned\n");
        break;
    }
    default: {
        printf ("Scanned %d\n", num);
        break;
    }
}

Upvotes: 4

Matthew Flaschen
Matthew Flaschen

Reputation: 284836

From the docs:

"If the input ends before the first matching failure or conversion, EOF shall be returned. If a read error occurs, the error indicator for the stream is set, EOF shall be returned"

Note that it is returned, rather than being read into the pointer you pass.

To distinguish between an error and EOF you can use feof.

Upvotes: 2

Related Questions