scanf("%c",&x) 和 x=getchar() 有区别吗?

Is there difference between scanf("%c",&x) and x=getchar()?

我写这篇文章是为了尽可能多地理解我试图计算的以下程序,因为我认为它在日常生活中有一些可能的应用。

程序是这样的(这是一个密码):

#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;
}

如您所见,我正在尝试移动输入中给定的某个常量的字母表。

我不是很理解也不是很了解的事情是为什么没有 scanfgetchar 程序就不能运行,两者都是相同的价值,让我们在这里说:

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

我认为这两者是完全等价的;事实上,在互联网上搜索时,我发现这个问题 getchar:

This function returns the character read as an unsigned char cast to an int or EOF on end of file or error.

这正是我所期望的 scanf() 所做的。

我发现:

是的,有一些不同。

主要是读取字符失败时的行为。 (通常这可能是由于输入流被关闭导致的,但也有其他原因导致读取失败)。

scanf 函数通过其 return 值指示失败。如果您不检查 return 值(因为您没有在代码中检查),那么您将无法知道读取是否失败。在这种失败情况下,d 可能会保留其旧值,但我不确定标准是否保证了这一点。

getchar() 通过 returning EOF 表示失败,这是一个负整数值(通常是 -1 但不保证一定是)。在您的代码中,您编写了 d=getchar(),这意味着您无法将此结果与具有与 EOF 相同字符代码的字符的有效读取区分开来。 (常见系统的字符在 -128127 范围内)。 d 将永远不会保留此代码的先前值。

为了正确处理错误,您可以使用 scanf 并测试 return 值为 1;或将 getchar() 的结果存储在 int 中,并在继续将其分配给 char.

之前检查该值不是 EOF

成功案例也存在理论上的差异。这与现代系统无关。 scanf 版本会将成功的字符存储在 d 中。但是,getchar() 版本 return 是一个非负整数,它是转换为 unsigned char 的字符。代码 d=getchar() 然后涉及将此值转换为 char。如果 char 被签名,这将调用实现定义的行为,并且它可能会导致与您从 scanf 获得的字符代码不同的字符代码。我不知道有任何系统存在,但实际上会有所不同。


两个版本都从流中读取下一个可用字符。在问题的底部,您描述了一些其他行为,但我认为您将 scanf"%d" 的行为与 "%c".

的行为混淆了

在你的程序中,如果你从未遇到另一个与 d 相同的字符,while (b != d) 将永远不会终止,你需要解决这个问题并确保它在读取失败时终止。