本博客可以了解一些gets/puts/scanf/printf/getchar函数的基本用法。
gets
函数从标准输入读取一行文本并把它存储于作为参数传递给它的数组中。一行输入由一串字符组成,以一个换行符(newline)结尾。gets
函数丢弃换行符,并在该行的末尾存储一个NUL字节(一个NUL字节是指字节模式为全0的字节,类似’\0’这样的字符常量)。然后,gets函数返回一个非NULL值,表示该行已被成功读取。当gets
函数被调用但事实上不存在输入行时,它就返回NULL值,表示它到达了输入的末尾(文件尾)。
字符串就是一个以NUL字节结尾的字符。NUL是作为字符串终止符,如
"Hello"
在内存中占据6个字节的空间,按顺序分别是H、e、l、l、o和NUL。
gets
常常按下面使用,读取一行以后进行相应的操作。
while( gets( input ) != NULL )
{
//操作
}
puts
函数是gets
函数的输出版本,它把指定的字符串写到标准输出并在末尾添上一个换行符。例如输出一行字符串:
puts( "Last column number is not paired." );
scanf
函数接受几个参数,其中第1个参数是一个格式字符串(如%s
),用于描述期望的输入类型。剩余几个参数都是变量,用于存储函数所读取的输入数据。scanf函数的返回值是函数成功转换并存储于参数中的值的个数。
例子:
定义一个数组array和一个整型数number。
int array[5];
int number;
由于scanf函数的实现原理,所有标量参数的前面必须加上一个“&”符号。数组参数前面不需要加上“&”符号,它本身代表第一个数组元素的地址。
scanf("%d", array);
但是,数组参数中如果出现了下标引用,也就是说实际参数是数组的某个特定元素,那么它的前面也必须加上“&”符号。
scanf("%d", &array[2]);
格式码%d
表示需要读取一个整型值。字符是从标准输入读取,前面的空白将被跳过。然后这些数字被转换为一个整数,结果存储于指定的数组元素中。我们需要在参数前加上一个“&”符号,因为数组下标选择的是一个单一的数组元素,它是一个标量。
输入的number也是一个特定的元素,也要加上“&”符号。
scanf("%d", &number);
使用所有格式码(除了%c
之外)时,输入值之前的空白(空格、制表符、换行符等)会被跳过,值后面的空白(空格、制表符、换行符等)表示该值的结束。因此,用%s
格式码输入字符串时,中间不能包含空白。除了表中所列之外,还存在许多格式代码,但这张表里面的这几个格式代码对于应付我们现在的需求已经足够了。
scanf函数每次调用时都从标准输入读取一个符合格式码的输入字符。如果转换失败,不管是因为文件已经读完还是因为下一次输入的字符无法转换为符合格式码的数据,函数都会返回0,这样就会使整个循环终止。如果输入的字符可以合法地转换为符合格式码的数据,那么这个值就会转换为二进制数存储于变量元素中。然后,scanf函数返回1。
附scanf
常见的格式码
格式码 | 含义 | 数据类型 |
---|---|---|
%d | 整型 | int |
%ld | 长整型 | long |
%f | 单精度浮点型 | float |
%lf | 双精度浮点型 | double |
%c | 字符 | char |
%s | 字符串 | char型数组 |
printf
函数接受多个参数,其中第一个参数是一个字符串,描述输出的格式,剩余的参数就是需要打印的值。格式常常以字符串常量的形式出现。
例如:
char input = 'a';
printf( "Original input : %c\n", input);
结果是:
Original input : a
附printf
常见的格式码
格式码 | 含义 | 数据类型 |
---|---|---|
%d | 十进制整型 | int |
%o | 八进制整型 | int |
%x | 十六进制整型 | long |
%g | 浮点值 | float |
%s | 字符串 | char型数组 |
getchar
函数从标准输入读取一个字符并返回它的值。如果输入中不再存在任何字符,函数就会返回常量EOF(在stdio.h中定义),用于提示文件的结尾。
我们可以这样写:
ch = getchar();
while( ch != EOF && CH != '\n' )
ch = getchar();
上面的语句将读取一个字符,接下来如果我们尚未到达文件的末尾或读取的字符并不是换行符,它将继续读取下一个字符。从getchar
函数返回的值被赋给变量ch
,然后把它与EOF
进行比较。在赋值表达式两端加上括号用于确保赋值操作先于比较操作进行。如果ch
等于EOF
,整个表达式的值就为假,循环将终止。若非如此,再把ch
与换行符进行比较,如果两者相等,循环也将终止。因此,只有当输入尚未到达文件尾并且输入的字符并非换行符时,表达式的值才是真的(循环将继续执行)。这样,这个循环就能剔除当前输入行最后的剩余字符。
注意出现了两次下面的语句:
int ch;
ch = getchar();
C语言可以把赋值操作蕴含于while语句内部,这样就允许程序员消除冗余语句。
于是我们可以这样改写:
while( (ch = getchar()) != EOF && ch != '\n' )
;
while语句之后的单独一个分号称为空语句 (empty statement),它就是应用于目前这个场合,也就是语法要求这个地方出现一条语句但又无需执行任何任务的时候。这个分号独占一行,这是为了防止被错误地以为接下来的语句也是循环体的一部分。
Q:为什么ch被声明为整型,而我们事实上需要它来读取字符?
因为EOF是一个整型值,它的位数比字符类型要多,把ch声明为整型可以防止从输入读取的字符意外地被解释为EOF。但同时,这也意味着接收字符的ch必须足够大,足以容纳EOF,这就是ch使用整型值的原因。
它与getchar
函数相对应,它接受一个整型参数,并在标准输出中打印该字符(如前所
述,字符在本质上也是整型)。
参考