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;
}
如您所见,我正在尝试移动输入中给定的某个常量的字母表。
我不是很理解也不是很了解的事情是为什么没有 scanf
或 getchar
程序就不能运行,两者都是相同的价值,让我们在这里说:
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()
所做的。
我发现:
如果我把所有字符都没有空格,我得到(我认为)只是相同字符的双字母而不是两个的移位。
while
中的 else
无法按预期工作,因为一旦我输入与字母字符不同的字符并看到结果,输出就会失败该字符的无限字符串。
是的,有一些不同。
主要是读取字符失败时的行为。 (通常这可能是由于输入流被关闭导致的,但也有其他原因导致读取失败)。
scanf
函数通过其 return 值指示失败。如果您不检查 return 值(因为您没有在代码中检查),那么您将无法知道读取是否失败。在这种失败情况下,d
可能会保留其旧值,但我不确定标准是否保证了这一点。
getchar()
通过 returning EOF
表示失败,这是一个负整数值(通常是 -1
但不保证一定是)。在您的代码中,您编写了 d=getchar()
,这意味着您无法将此结果与具有与 EOF
相同字符代码的字符的有效读取区分开来。 (常见系统的字符在 -128
到 127
范围内)。 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)
将永远不会终止,你需要解决这个问题并确保它在读取失败时终止。
我写这篇文章是为了尽可能多地理解我试图计算的以下程序,因为我认为它在日常生活中有一些可能的应用。
程序是这样的(这是一个密码):
#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
:
This function returns the character read as an
unsigned char
cast to anint
orEOF
on end of file or error.
这正是我所期望的 scanf()
所做的。
我发现:
如果我把所有字符都没有空格,我得到(我认为)只是相同字符的双字母而不是两个的移位。
while
中的else
无法按预期工作,因为一旦我输入与字母字符不同的字符并看到结果,输出就会失败该字符的无限字符串。
是的,有一些不同。
主要是读取字符失败时的行为。 (通常这可能是由于输入流被关闭导致的,但也有其他原因导致读取失败)。
scanf
函数通过其 return 值指示失败。如果您不检查 return 值(因为您没有在代码中检查),那么您将无法知道读取是否失败。在这种失败情况下,d
可能会保留其旧值,但我不确定标准是否保证了这一点。
getchar()
通过 returning EOF
表示失败,这是一个负整数值(通常是 -1
但不保证一定是)。在您的代码中,您编写了 d=getchar()
,这意味着您无法将此结果与具有与 EOF
相同字符代码的字符的有效读取区分开来。 (常见系统的字符在 -128
到 127
范围内)。 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)
将永远不会终止,你需要解决这个问题并确保它在读取失败时终止。