scanf(“%c”,&x)和x = getchar()之间有区别吗?

时间:2018-10-21 10:09:01

标签: c function scanf 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

  

此函数返回在文件或错误结束时作为unsigned char强制转换为intEOF的字符。

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

我发现:

  • 如果我将所有字符都放在不带空格的位置上,我会(我认为)只是将相同字符转换成双字母而不是两个。

  • else中的while不能按预期工作,因为我立即输入了与字母不同的字符,并看到结果输出失败字符。

1 个答案:

答案 0 :(得分:2)

是的,有一些区别。

主要问题是在读取字符失败的情况下的行为。 (通常这可能是由于输入流被关闭而发生的,但是还有其他导致读取失败的原因。)

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

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

为了正确处理错误,您可以使用scanf并测试返回值为1;或将getchar()的结果存储在int中,并在将值分配给EOF之前检查值是否不是char


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


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

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