Когда моя программа читает CTRL-D из стандартного ввода в Linux, почему она не конвертируется в EOF? - PullRequest
0 голосов
/ 03 апреля 2012

Ниже приведена программа, которую я написал.

/*******************************************************************************
 * 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()

Я скомпилировал с помощью gcc в Ubuntu 11.10.Он не распознает Ctrl - D для EOF в программе и выдает 0 при попытке напечатать его значение.Выходные данные для вышеуказанной программы на моем терминале ниже.

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

ПРИМЕЧАНИЕ. Терминал CTRL-D не отражается от терминала, когда я нажимаю его для двух входов, следовательно, не виден при выполнении вышеуказанной программы.

Я прочитал, что EOF определяется как целое число в stdio.h и stdlib.h и традиционно определяется как -1.Также я понимаю, что Ctrl - D имитирует EOF для стандартного ввода.Тогда почему он не переводится в -1 при сохранении его в целочисленной переменной?

Ответы [ 2 ]

4 голосов
/ 03 апреля 2012

Поскольку scanf("%d") попытается прочитать символы, представляющие число, а затем сохранить их в заданной переменной.

Он не сохраняет EOF в число, если вы закрываете поток. В противном случае, как бы вы определили разницу между концом файла и вводом числового значения EOF (-1).

scanf вернет количество отсканированных элементов (которое будет равно нулю, если формат был неправильным, или EOF, если поток закрыт или произошли определенные ошибки). Он возвращает это как код возврата из функции scanf, , а не через переменную-указатель, которую вы ей передали.

Вы должны только предполагать, что переменные (для которых вы передаете адреса) заполняются, если возвращаемое значение из scanf говорит вам об этом.

Другими словами, вы ищете что-то вроде:

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;
    }
}
2 голосов
/ 03 апреля 2012

С документы :

"Если ввод заканчивается до первого сбоя или преобразования сопоставления, должен быть возвращен EOF. Если происходит ошибка чтения, устанавливается индикатор ошибки для потока, должен возвращаться EOF"

Обратите внимание, что оно возвращается, а не считывается в указатель, который вы передаете.

Чтобы различать ошибку и EOF, вы можете использовать feof.

...