2011-04-12 148 views
5

我想知道标准C库函数scanf()在我们调用scanf(“%d”,& var)时,如果输入是整数或字符,当一个字符本身只是一个数字时,该如何检查? 我知道当它遇到一个非整数时,它将它放回到输入缓冲区并返回一个-1,但它怎么知道输入不是一个整数?scanf()如何检查输入是整数还是字符?

回答

3

你说得对,因为每个字符都被表示为一个8位整数。解决办法很简单:查看该号码,看它是否在48-57范围内,这是字符'0' - '9'的SCII代码范围。

scanf()source code的行1315开始,我们可以看到这一行动。 scanf()实际上更复杂 - 它也会查看多字节字符来确定数值。 1740行是魔法发生的地方,而角色实际上被转换为数字。最后,可能这是最有用的,strtol()函数执行循环来执行该转换。

+0

感谢您对源代码的解释和参考! – vjain27 2011-04-12 03:09:28

3

输入始终是一个字符串。如果scanf正期待一个整数(因为您通过它"%d"),它会尝试将字符串转换为一个整数。

+0

但是无论我们投入这将是全数字的ASCII值的序列。不是吗? – vjain27 2011-04-12 01:42:55

+0

代表数字的ASCII值,你的意思。 scanf采用字符'9',决定它代表一个数字,并将其转换为整数9. – Marvo 2011-04-12 01:44:41

+0

是的,这就是它应该做的。键盘只会发送ascii字符。 – vjain27 2011-04-12 01:50:51

0

它试图从流的开头解析一个有效的十进制整数,实际上是可选的+或 - 然后是一个或多个数字的序列。

+0

你能解释一下它是如何解析的?例如。它将如何区分A和65的值,因为A将以65的形式传递 - 它的ASCII值? – vjain27 2011-04-12 01:47:58

+0

Uh scant尝试在此处读取十进制整数的ASCII表示。字母A不是这样的一部分。 – 2011-04-12 01:54:22

0

它基本上使用像一个循环:

while (isdigit((ch=getchar())) 
    // ... 
+0

我明白了。谢谢! – vjain27 2011-04-12 03:08:56

0

你误会了%d格式说明。它不是而是返回输入字符的ASCII值(可以使用%c表示);它返回字符表示的整数。因此,在'9'的输入字符上,%d返回值9--而不是'9'的ASCII值。

(好吧,其实%d着眼于字符序列,因此,如果输入的是随后'0'其次' ''9',它会解释,由于90)。

1

基本上,scanf函数根据您传递的转换说明符匹配正则表达式。如果您指定%d,则告知scanf将输入与'0''9'(可选带有前导+-字符)之间的一个或多个字符的正则表达式匹配。然后它将该字符序列转换为等效的整数值。

一个非常简单的版本可能是这个样子:

while (isdigit(c = fgetc(stream)) 
    val = val * 10 + valueOf(c); 
ungetc(c, stream); 

其中isdigit是一个标准库函数返回true(非零)如果字符值表示十进制数字,和valueOf是一个用户定义的函数将表示整数('0'-'9')的字符映射为等效整数值(0-9)(我不知道标准库函数会为单个字符值执行此操作)。为什么不从c减去'0'以获得等效的整数值?根据编码的不同,不能保证所有的十进制整数字符都会按顺序排列(All The World is Not ASCII);最好将实际转换委托给知道当前编码的函数。

2

在你提的这是默认控股整数只有那么%d scanf函数声明,它理解该变量作为整数

相关问题