您的位置:首页 > 其它

Scanf函数的输入问题

2016-02-05 20:14 267 查看
scanf() 怎样读取输入?


scanf() 开始读取输入以后,会在遇到的第一个空白字符空格(blank)、制表符(tab)或者换行符(newline)处停止读取。

假定使用了一个%d说明符来读取一个整数。scanf() 函数开始每次读取一个输入字符,它跳过空白字符(空格、制表符和换行符)直到遇到一个非空白字符。因为它试图读取一个整数,所以scanf() 期望发现一个数字字符或者一个符号(+或者-)。如果它发现了一个数字或一个符号,那么它就保存之并读取下一个字符;如果接下来的字符是一个数字,它保存这个数字,并读取下一个字符。就这样,scanf() 持续读取和保存字符直到它遇到一个非数字的字符。如果遇到了一个非数字的字符,它就得出结论:已经到了整数的尾部。scanf()把这个非数字字符放回输入。这就意味着当程序下一次开始读取输入时,它将从前面被放弃的那个非数字字符开始。最后,scanf() 计算它读取到的数字的相应数值,并将该值放到指定的变量中。

如果使用了字段宽度,那么scanf() 在字段结尾或者在第一个空白字符处(而这中最先到达的一个)终止。

如果第一个非空白字符不是数字,将会发生什么呢?比如说,是A而非一个数字?这时scanf() 会停在那里,并把A(或者不管是什么)放回输入。没有把任何值赋给指定的变量,程序下一次读取输入时,它就在A处重新开始。如果程序中只有%d说明符,scanf() 永远也不会越过那个A(去读下一个)。而且,如果使用带有多个说明符的scanf()语句,ANSI C要求函数在第一个出错的地方停止读取输入。

使用其他数字说明符读取输入与使用%d的情况相同。主要的区别在于scanf()也许会把更多的字符看作数字的一部分。例如,%x说明符要求scanf()识别十六进制数字a到f和A到F。浮点说明符要求scanf() 识别小数点、指数记数法(e-notation)、新的p记数法(p-notation)。

如果使用%s说明符,那么空白字符以外的所有字符都是可以接受的,所以scanf() 跳过空白字符直到遇到第一个非空白字符,然后保存再次遇到空白字符之前的所有非空白字符。这就意味着%s使scanf() 读取一个单词,也就是说,一个不包含空白字符的字符串。如果使用字段宽度,scanf() 在字段的结尾或者第一个空白字符处停止。不能通过字段宽度使得scanf() 用一个%s说明符读取多于一个字的输入。最后一点:当scanf() 把字符串放在一个指定的数组中时,它添加终止的’\0’使得数组内容成为一个C字符串。

如果使用%c说明符,那么所有的输入字符都是平等的。如果下一个输入字符是一个空格或者换行符,将会把这个空格或换行符赋给指定的变量;不会跳过空白字符。

scanf() 函数允许把普通字符放在格式字符串中。除了空格字符之外的普通字符一定要与输入字符串准确匹配。格式字符串中的空格意味着跳过下一个输入项之前的任何空格。(“任何空格”的概念包括没有空格的特殊情况)

除了%c以外的说明符会自动跳过输入项之前的空格,所以scanf(“%d%d”, &n, &m) 与scanf(“%d %d”, &n, &m) 的行为是相同的。对于%c来说,向格式字符串中添加一个空格将导致一些区别。例如:如果在格式字符传中%c之前有一个空格,那么scanf() 会调到第一个非空白字符处。也就是说,命令scanf(“%c”, &ch) 读取在输入中遇到的第一个字符,而scanf(“ %c”, &ch) 则读取遇到的第一个非空白字符。

scanf() 函数返回成功读入的项的个数 。如果没有读取任何项目(当它期望一个数字却键入了一个非数字字符串时就会发生这种情况),scanf() 会返回值0。当它检测到“文件结尾”(end of file)时,它返回EOF(EOF – End Of File,EOF是在文件stdio.h中定义的特殊值,一般,#define 指令把EOF的值定义为-1)。

总结:

空白字符(制表符、空格和换行符)对于scanf() 如何处理输入起着至关重要的作用。除了在%c模式(它读取下一个字符)下外,在读取输入时,scanf() 会跳过空白字符直到第一个非空白字符处。然后它会一直读取字符,直到遇到空白字符,或遇到一个不符合正在读取的类型的字符。考虑如果让几个不同的scanf() 输入模式读取相同的输入行,将会产生什么情况。假如有如下输入行:

-13.45e12# 0

注意,#和0之间有一个空格。

首先,假定使用%d模式,scanf() 会读取三个字符(-13)并在小数点处停止,将小数点作为下一个输入字符。然后,scanf() 将会把字符序列-13转换成相应的整数数值,并将该值存储在目标整型变量中。

接着,假定scanf() 以%f模式读取相同的行,它将会读取字符-13.45e12,并在#符号处停止,将它作为下一个输入字符。然后它把字符序列-13.45e12转换成相应的浮点数值,并将改制存储在目标浮点变量中。

假定scanf() 以%s模式读取相同的行,它将会读取-13.45e12#,并在空格处停止,将这个空格作为下一个输入字符。然后他将把这10个字符的字符代码存储到目标字符数组中,并在结尾附加一个空字符。

最后假定scanf() 使用%c说明符读取相同的行,它将会读取并存储第一个字符,在这里是一个空格。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: