Есть ли разница между scanf ("% c", & x) и x = getchar ()? - PullRequest
0 голосов
/ 21 октября 2018

Я пишу, чтобы как можно лучше понять следующую программу, которую я пытался вычислить, потому что я думал, что у нее есть какое-то возможное применение для повседневной жизни.

Программа выглядит так (этоcypher):

#include <stdio.h>

void cifrario(int k) {
    char b, d;
    scanf("%c", &d);
    d = getchar();
    putchar(d);
    scanf("%c", &b);
    b = getchar();
    while (b != d) {
        if (('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z')) {
            b = b + k;
            printf("%c", b);
            scanf("%c", &b);
            b = getchar();
        } else 
            printf("%c", b);
    }
}

int main() {
    int h;
    scanf("%d", &h);
    cifrario(h);
    return 0;
}

Как видите, я пытаюсь сместить алфавит определенной константы, заданной на входе.

Вещи, которые я не совсем понимаю, и я 'Я не совсем понимаю, почему программа не должна функционировать без scanf или getchar, и оба необходимы для одного и того же значения, скажем здесь:

scanf("%c", &d);
d = getchar(); 

Я думал, что эти два былиполностью эквивалентный;фактически, выполняя поиск в Интернете, я обнаружил, что это касается getchar:

. Эта функция возвращает символ, прочитанный как приведенный unsigned char, к int или EOF в концефайл или ошибка.

Это то, что я ожидал scanf() сделал.

Я обнаружил, что:

  • , если я поставлю всесимвол без пробелов Я получаю (я думаю) просто смещение одного и того же символа для двойной буквы вместо двух.

  • else в while не работаеткак и ожидалось, потому что, как только я поместил символ, отличный от буквенного, и увидел результат, вывод завершился ошибкой в ​​бесконечной строке этого символа.

1 Ответ

0 голосов
/ 22 октября 2018

Да, есть некоторые различия.

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

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

getchar() указывает на сбой, возвращая EOF, что является отрицательным целым значением(обычно -1, но не гарантировано).В вашем коде вы пишете d=getchar(), что означает, что вы не можете отличить этот результат от действительного чтения символа с тем же кодом символа, что и EOF.(Обычные системы имеют символы в диапазоне от -128 до 127).d никогда не сохранит свое предыдущее значение для этого кода.

Чтобы правильно справиться с ошибками, вы либо используете scanf и проверяете возвращаемое значение 1;или сохраните результат getchar() в int и убедитесь, что значение не равно EOF, прежде чем назначать его для char.


Существует также теоретическая разница вслучай успеха.Это не относится к современным системам.Версия scanf сохранит успешного персонажа в d.Однако версия getchar() возвращает неотрицательное целое число, то есть символ, преобразованный в unsigned char.Затем код d=getchar() включает преобразование этого значения в char.Если char подписано, это вызывает поведение, определяемое реализацией, и это может привести к тому, что код символа будет отличаться от того, что вы получили бы от scanf.Однако я не знаю ни одной системы, которая когда-либо существовала, где это могло бы отличаться.


Обе версии читают следующий доступный символ из потока.В нижней части вашего вопроса вы описываете другое поведение, но я думаю, что вы путаете поведение scanf с "%d" с "%c".

В вашей программе while (b != d) никогда не завершитсяесли вы никогда не сталкиваетесь с другим символом, таким как d, вам нужно исправить эту проблему и убедиться, что она прекращается при сбое чтения.

...