type
status
date
slug
summary
tags
category
icon
password
Property
C库包含了多个输入函数,
scanf()
是最通用的一个,因为它可以读取不同格式的数据。当然,从键盘输入的都是文本,因为键盘只能生成文本字符:字母、数字和标点符号。如果要输入整数 2014,就要键入字符 2、0、1、4。如果要将其储存为数值而不是字符串,程序就必须把字符依次转换成数值,这就是
scanf()
要做的。scanf()
把输入的字符串转换成整数、浮点数、字符或字符串,而printf()
正好与它相反,把整数、浮点数、字符和字符串转换成显示在屏幕上的文本。
scanf()
和printf()
类似,也使用格式字符串和参数列表。scanf()
中的格式字符串表明字符输入流的目标数据类型。两个函数主要的区别在参数列表中。printf()
函数使用变量、常量和表达式,而scanf()
函数使用指向变量的指针。这里只需记住以下两条简单的规则:- 如果用
scanf()
读取基本变量类型的值,在变量名前加上一个&;
- 如果用
scanf()
把字符串读入字符数组中,不要使用&。
scanf()
函数使用空白(换行符、制表符和空格)把输入分成多个字段。在依次把转换说明和字段匹配时跳过空白。只要在每个输入项之间输入至少一个换行符、空格或制表符即可,可以在一行或多行输入。唯一例外的是%c转换说明。根据%c,scanf()会读取每个字符,包括空白。
scanf()的转换说明
scanf()
函数所用的转换说明与printf()
函数几乎相同。主要的区别是,对于float类型和double类型,printf()都使用%f、%e、%E、%g和%G转换说明。而scanf()只把它们用于float类型,对于double类型时要使用l修饰符。从scanf()角度看输入
假设
scanf()
根据一个%d转换说明读取一个整数。scanf()
函数每次读取一个字符,跳过所有的空白字符,直至遇到第1个非空白字符才开始读取。因为要读取整数,所以scanf()
希望发现一个数字字符或者一个符号(+或-)。如果找到一个数字或符号,它便保存该字符,并读取下一个字符。如果下一个字符是数字,它便保存该数字并读取下一个字符。scanf()
不断地读取和保存字符,直至遇到非数字字符,便认为读到了整数的末尾。然后,scanf()
把非数字字符放回输入。这意味着程序在下一次读取输入时,首先读到的是上一次读取丢弃的非数字字符。最后,scanf()
计算已读取数字(可能还有符号)相应的数值,并将计算后的值放入指定的变量中。
如果使用字段宽度,
scanf()
会在字段结尾或第1个空白字符处停止读取。如果第1个非空白字符是A而不是数字,会发生什么情况?
scanf()
将停在那里,并把A放回输入中,不会把值赋给指定变量。程序在下一次读取输入时,首先读到的字符是A。如果程序只使用%d转换说明, scanf()
就一直无法越过A读下一个字符。另外,如果使用带多个转换说明的scanf()
,C规定在第1个出错处停止读取输入。
用其他数值匹配的转换说明读取输入和用%d 的情况相同。区别在于scanf()
会把更多字符识别成数字的一部分。例如,%x转换说明要求scanf()识别十六进制数a~f和A~F。浮点转换说明要求scanf()识别小数点、e记数法(指数记数法)和新增的p记数法(十六进制指数记数法)。
如果使用%s 转换说明,scanf()
会读取除空白以外的所有字符。scanf()
跳过空白开始读取第 1 个非空白字符,并保存非空白字符直到再次遇到空白。这意味着 scanf()
根据%s 转换说明读取一个单词,即不包含空白字符的字符串。如果使用字段宽度,scanf()
在字段末尾或第1个空白字符处停止读取。无法利用字段宽度让只有一个%s的scanf()
读取多个单词。最后要注意一点:当scanf()
把字符串放进指定数组中时,它会在字符序列的末尾加上'\0',让数组中的内容成为一个C字符串。
实际上,在C语言中
scanf()
并不是最常用的输入函数。还有其他的输入函数,如 getchar()
和 fgets()
。这两个函数更适合处理一些特殊情况,如读取单个字符或包含空格的字符串。格式字符串中的普通字符
scanf()
函数允许把普通字符放在格式字符串中。除空格字符外的普通字符必须与输入字符串严格匹配。例如,假
设在两个转换说明中添加一个逗号:scanf()
函数将其解释成:用户将输入一个数字、一个逗号,然后再输入一个数字。也就是说,用户必须像下面这
样进行输入两个整数:
由于格式字符串中,%d后面紧跟逗号,所以必须在输入88后再输入一个逗号。但是,由于scanf()会跳过整数前面
的空白,所以下面两种输入方式都可以:
格式字符串中的空白意味着跳过下一个输入项前面的所有空白。例如,对于下面的语句:
以下的输入格式都没问题:
请注意,“所有空白”的概念包括没有空格的特殊情况。
除了%c,其他转换说明都会自动跳过待输入值前面所有的空白。因此
scanf("%d%d", &n, &m)
与scanf("%d %d", &n, &m)
的行为相同。对于%c,在格式字符串中添加一个空格字符会有所不同。例如,如果把%c放在格式字符串中的空格前面,
scanf()
便会跳过空格,从第1个非空白字符开始读取。也就是说,scanf("%c", &ch)
从输入中的第1个字符开始读取,而scanf(" %c", &ch)
则从第1个非空白字符开始读取。scanf()的返回值
scanf()函数返回成功读取的项数。如果没有读取任何项,且需要读取一个数字而用户却输入一个非数值字符串,scanf()便返回0。当scanf()检测到“文件结尾”时,会返回EOF。
EOF是
stdio.h
中定义的特殊值,通常用#define指令把EOF定义为-1