C语言教程-3_2-基本输入输出
理解输入输出
什么是交互
程序是为人服务的,程序计算出来的所有数据,最终都以各种不同的方式来间接或直接地提供给我们,也就是输出
.
同样,程序在运行时,我们往往也需要为其提供一些必要的数据,作为输入
.
程序根据我们输入的信息来进行处理,并将结果显示出来.
最基本的输入输出操作,就是在控制台屏幕使用键盘进行交互,我们将需要输入的数据使用键盘
来输入,程序将需要输出的数据显示在屏幕
上.这种输入输出叫做标准输入输出
.
在标准输入输出
中,往往使用电脑显示器
来作为标准输出的目标,使用键盘
来作为标准输入的来源.
本章我们要讲的就是标准输入输出
,也就是Standard input/output
.即简单地使用键盘输入,从屏幕上看到输出信息.
什么是流
许多资料都会引入流
这个概念,输入输出也是一种流.
流(Stream)
是一个抽象的概念,表示数据从一个地方流向另一个地方,或者数据从一个源生成,并最终被传递到目的地。流可以是字节流(以字节为单位处理数据)或字符流(以字符为单位处理数据).
我们之前存储的数据全部是固定存储在某个地方,我们直接通过地址等方式进行引用即可找到,但是流数据不同.
可以将存储的数据类比为水池中的水,流数据类比为水流.存储的数据是相对固定的
,我们可以反复进行存取,例如电脑中存储的一张照片,一段视频;而流数据往往代表的是某个数据源即时生成的
数据,直接依次传输到目的地,例如键盘读取的一系列敲击操作.
标准输入输出就是这样的一类流.
在进行标准输入
时,也即从键盘进行读取,键盘就是一个标准输入流设备
,从键盘读入的数据不需要进行缓冲
,直接逐个进行传输即可,就像水流
一样.
同理,在进行标准输出
是,也即向屏幕显示,也是将其视为数据流来"流"向屏幕(实际上是终端),并逐个打印到屏幕上.
或者,读者可能知道"流媒体"
这个概念.与键盘这样的流设备
对应的,还有块设备
,例如硬盘,它们需要一个成块的空间来进行缓冲
,数据的读取是成块成块的.
关于流
的简单讲解就这么多,我们只需要知道,本章讲解的就是对标准输入输出流进行操作.
C语言对标准输入输出的支持
stdio.h
我们前面看到很多程序的开头都有#include <stdio.h>
这行指令,但是并没有深究其作用,实际上,它就是为我们的程序提供了标准输入输出的支持.
#include预处理指令
用于引入头文件,这里引入的就是C标准库的stdio.h
头文件,这个头文件中定义,声明了有关输入输出的各种内容.想必各位可能已经意识到,stdio
,即standard in/out
的缩写.
当然,C可以支持的输出输出不仅仅有标准IO(即标准输入输出,以下均简写为标准IO),还有文件IO,网络IO,内存IO等等,它们往往更加复杂,需要更多的处理,但是殊途同归,它们都是数据操作,并且往往都是视为流去处理.
在stdio.h中有许多函数声明,和一些常用的宏,下面进行简单列举:
输入输出函数
函数 | 功能 |
---|---|
scanf()函数 | 用于格式化输入 |
printf()函数 | 用于格式化输出 |
puts()函数 | 用于输出字符串,并自动加上换行符 |
gets()函数 | 输入一个字符串,同时会接受除了'\n' 的其他空白字符.(由于有严重的安全缺陷已弃用) |
putchar()函数 | 输出单个字符 |
getchar()函数 | 输入单个字符 |
三个流
预定义 | 关联 |
---|---|
#define stdin /* implementation-defined */ | 标准输入流 |
#define stdout /* implementation-defined */ | 标准输出流 |
#define stderr /* implementation-defined */ | 标准错误流 |
这些宏展开成 FILE* 类型表达式(即它们是文件指针)
常用函数讲解
C风格字符串
这里简单讲解一下字符串:
C语言中,字符串是由一对""
和其包括起来的任意数量的字符组成.
例如,我们想要表示Hello world!
这行字符串,就是这么写:
"Hello world!"
任何可以放到char变量中的字符,都可以出现在字符串中.
printf()函数
基本用法
函数原型如下:
int printf( const char *restrict format, ... );
printf函数名实际就是print formatted的缩写,意即打印格式化的字符串.
可以看到printf函数的第一个参数是一个字符串,后面可以继续接任意个数的其他参数(函数参数的内容将在后面讲解函数时详细展开).
函数的返回值为最终打印的字符个数.
printf()函数用于根据我们的格式要求生成一个最终的字符串,来打印到我们的终端(输出),这个字符串可以由多个字符串,多个整数,多个字符,多个浮点数等等拼接而成.
参数的第一个字符串就是用于描述这些数据如何进行拼装的,也即所谓的格式化字符串,用于描述输出格式.
我们说的各个数据就是后面可以追加的若干任意数量的参数,它们可以是任意数据类型的值.
printf函数的最基本用法就是输出一个字符串常量:
1 |
|
但是printf函数的强大是体现在这个格式化字符串的,这个字符串中可以加入一些指定好的格式指示符
,来进行额外的格式化操作,举一个简单的例子:
1 |
|
输出结果为:

可以看到123前面有2个空格," 123"
一共占用5个字符的宽度,即格式化字符串中的%5d用于将后面的第一个整型参数i输出,并保证至少占用5位的宽度,并插入到其他的"Hello"
和"!"
中间,最终生成"Hello 123!"
这个字符串打印到终端.
这里%5d
就是一种格式指示符
,与此类似的格式指示符
还有很多,我们列举一些常用的.
格式指示符
这里引用了《C Primer Plus (第6版)》的内容:
读者请自行理解试验,需要用到哪种控制符可以去查找表格学习用法.
注意
1.对于浮点数,为了安全起见,printf函数将所有float类型的参数都提升为double类型(对未使用显式类型原型的所有C函数都有效).
2.如果格式化字符串较长,可以在一行结尾加上\
来转义换行符(下一行必须从最开始开始,否则缩进就会变成字符串的一部分),或者使用两个字符串进行拼接:
1 |
|

3.还有一些表格中可能没有的格式指示符,例如%s
,它用于输出一个字符串:
1 | printf("Hello world!"); |
scanf()函数
基本用法
函数原型为:
int scanf( const char *restrict format, ... );
scanf()函数的功能和printf相反,它用于输入数据(scan意即"扫描")
同时,它也接受一个格式字符串和若干准备输入的参数,与printf不同的是,scanf后面的若干参数必须是合法的指针
.
函数的返回值为成功读取的参数个数.
读者此时不必疑惑指针
这个概念,你需要知道相比于printf,scanf后面的参数之前需要加上一个&字符
(实际上是取地址运算符),用来获取期待输入值的这个变量的地址(指针).
实际上很简单,我们想要对一个变量进行输入,就需要知道他的存储位置.
同时,scanf的格式化字符串不允许使用像printf那样多样的格式指示符
,我们仅仅需要使用例如:
%d来输入int类型的整数;
%s来输入字符串;
%f来输入float类型的浮点数;
%lf来输入double类型的浮点数;
%ld来输入long类型的整数…
等等…
格式指示符
C标准中的描述:
举例
例如我们需要输入两个int类型的值,赋值给i,j,应该这样写:
1 |
|

注意到,scanf中的两个%d
之间没有空格,我们输入时和printf中却需要空格,这是一个不同,事实上,scanf在输入整数/浮点数时,会不断读取,直到遇到不合法的字符为止—例如空格等空白符,逗号等字符.
该%d
结束后,再继续读取下一个%d
.
另一方面,scanf也允许使用一般字符,scanf会在读取时匹配这些字符(如果格式化字符串中有的话,则必须匹配,否则之后的变量会读取失败),然后简单地丢弃这个字符:
1 |
|
正确的输入:

错误的输入:

可以看到后两个变量并没有被正确地赋值,或者我们也可以输出scanf的返回值(成功读取的变量个数)来观察:
1 |
|

注意
1.不要在scanf中使用'\n',' '
等空白字符来结尾,例如:
scanf("%d%d%d ", &i, &j, &k);
scanf("%d%d%d\n", &i, &j, &k);
因为不同于printf,scanf函数的空白符代表忽略(匹配并丢弃)任意数量的空白字符,如果放在结尾,意味着这个scanf无法使用换行来结束输入!
2.(个人的建议)scanf中尽量只使用格式指示符,不要使用其他普通字符,做到简化输入.
getchar()函数
函数原型为:
int getchar( void );
该函数非常简单,用于读取一个字符:
1 | char c = getchar(); |
上面的代码和下面的代码等价:
1 | char c |
putchar()函数
函数原型为:
int putchar( int ch );
很简单,putchar('a');
就可以将一个字符a
输出.
其他(待扩充)
puts()和gets()将在讲解字符串时展开.
本章讲解了最常用的几个输入输出函数的使用,到现在我们多少掌握了printf和scanf的写法,需要在练习中不断熟悉.由于比较简单,可能例子不多.
自己多查资料.
---WAHAHA
上一篇:c语言教程-3_1-数据类型
下一篇:c语言教程-4-表达式和语句