第4章 数据输入、输出函数

视频讲解:52分钟

和其他高级语言一样,C语言的语句是用来向计算机系统发出操作指令的。当要求程序按照指令执行时,先要给它一个指示,这时就要使用向程序输入数据的方式;当程序解决了一个问题,还要使用输出的方式将计算的结果显示出来。

本章致力于使读者了解有关语句的概念,掌握如何对程序进行输入/输出操作,在本章中这些输入和输出操作将按照不同的方式进行讲解。

学习摘要:

 有关语句的概念

 单个字符数据的输入/输出操作

 如何输入/输出字符串

 操作数据的格式化输入和输出

4.1 语句

视频讲解

C语言的语句是用来向计算机系统发出操作指令的。一条语句编写完成经过编译后产生若干条机器指令。实际程序中包含若干条语句,所以语句的作用就是用来完成一定的操作任务。

注意

在编写程序时,声明部分不能算作语句。例如,“int iNumber;”就不是一条语句,因为不产生机器的操作,只是对变量提前的定义。

在前面的学习中,可以看到程序中包括声明部分和执行部分。其中执行部分即由语句组成。

4.2 字符数据输入/输出

视频讲解

动图演示

之前实例中,常常会使用到printf函数进行输出,使用scanf函数获取键盘的输入。

本节将介绍C标准I/O函数库中最简单的,也是很容易理解的字符输入/输出函数,即getchar函数和putchar函数。

4.2.1 字符数据输出

字符数据输出使用的是putchar函数,作用是向显示设备输出一个字符。该函数的定义如下:

int putchar(int ch);

使用时要添加头文件stdio.h,其中的参数ch为要进行输出的字符,可以是字符型变量、整型变量,或者是常量。例如输出一个字符A的代码如下:

putchar('A');

使用putchar函数也可以输出转义字符,例如输出字符A:

putchar('\101');

【例4.1】 使用putchar函数实现字符数据输出。(实例位置:资源包\源码\04\4.1)

在程序中使用putchar函数,输出字符串“Hello”并且字符串输出完毕之后进行换行。

运行程序,显示效果如图4.1所示。

图4.1 使用putchar函数实现字符数据输出

代码分析:

(1)要使用putchar函数,首先要包含头文件stdio.h。声明字符型变量,用来保存要输出的字符。

(2)为字符变量赋值时,因为putchar函数只能输出一个字符,如果要输出字符串时就要多次调用putchar函数。

(3)当字符串输出完毕之后,再使用putchar函数输出转义字符“\n”进行换行操作。

4.2.2 字符数据输入

字符数据输入使用的是getchar函数,此函数的作用是从终端(输入设备)输入一个字符。getchar函数与putchar函数不同的是getchar函数没有参数。

该函数的定义如下:

int getchar();

使用getchar函数时也要添加头文件stdio.h,函数的值就是从输入设备得到的字符。例如从输入设备得到一个字符赋给字符变量cChar:

cChar=getchar();

注意

getchar()只能接收一个字符。getchar函数得到的字符可以赋给一个字符变量或整型变量,也可以不赋给任何变量,还作为表达式的一部分。例如:

putchar(getchar());

getchar函数作为putchar函数的参数,当getchar从输入设备得到字符,然后putchar函数将字符输出。

【例4.2】 使用getchar函数实现字符数据输入。(实例位置:资源包\源码\04\4.2)

在本实例中,使用getchar函数获取在键盘上输入的字符,再利用putchar函数进行输出。同时演示了将getchar作为putchar函数表达式的一部分,进行输入和输出字符的方式。

运行程序,显示效果如图4.2所示。

程序代码如下:

代码分析:

(1)要使用getchar函数,首先要包括头文件stdio.h。

(2)声明变量cChar1,通过getchar函数得到输入的字符,赋值给cChar1字符型变量。之后使用putchar函数输出该变量。

(3)使用getchar函数得到在输入过程中输入的回车键。

(4)在putchar函数的参数位置,调用getchar函数得到字符,再将得到的字符输出。

在上面的程序分析中,看到有一处使用getchar函数接收回车键,这是怎么回事呢?原来在输入时,输入完A字符后,为了确定输入完毕要按回车键进行确定。其中的回车也算是字符,如果不进行获取,那么下一次使用getchar函数时将得到回车键。例如,上面的程序去掉调用getchar函数获取回车的语句,结果将如例4.3所示。

【例4.3】 使用getchar函数取消获取回车。(实例位置:资源包\源码\04\4.3)

运行程序,显示效果如图4.3所示。

图4.2 使用getchar函数实现字符数据输入

图4.3 使用getchar函数取消获取回车

程序代码如下:

在程序中将getchar函数获取回车的语句去掉,比较两个程序的运行情况。从程序的显示结果可以发现,程序没有获取第二次的字符输入,而是进行了两次的回车操作。

4.3 字符串输入/输出

视频讲解

动图演示

在上面的介绍中,可以看到putchar和getchar函数都只能对一个字符进行操作,这样要想进行一个字符串的操作就会变得很麻烦。对此,在C语言中,提供了两个函数用来对字符串进行操作,即gets函数和puts函数。

4.3.1 字符串输出函数

字符串输出使用的是puts函数,用来把输出的字符串显示到屏幕上。该函数的定义如下:

int puts(char *str);

使用该函数时,先要在其程序中添加stdio.h头文件。其中形式参数str是字符指针类型,可以用来接收要输出的字符串。例如,使用puts函数输出一串字符:

这行语句是输出一段字符串,之后会自动地进行换行操作。这与printf函数有所不同,在前面的实例中使用printf函数要进行换行时,要在其中添加转义字符“\n”进行换行操作。puts函数会在字符串中判断“\0”结束符,遇到结束符时,后面的字符不再输出并且自动换行。例如:

将上面的语句中加上“\0”字符后,这时puts函数输出的字符串就变成“I LOVE”。

说明

在前面的章节中,曾经介绍编译器会在字符串常量的末尾添加结束符“\0”,这也就说明为什么puts函数会在输出字符串常量时,最后进行换行操作。

【例4.4】 使用字符串输出函数进行显示信息提示。(实例位置:资源包\源码\04\4.4)

在本实例中,使用puts函数对字符串常量和字符串变量都进行操作,在这些操作中,学习观察使用puts函数的方法。

运行程序,显示效果如图4.4所示。

程序代码如下:

图4.4 字符串输出函数进行显示信息提示

代码分析:

(1)在程序代码中可以看到字符串常量赋值给字符串指针变量,有关字符串指针的内容将会在后面的章节进行介绍。此时可以将其看作整型变量,为其赋值后,就可以使用该变量。

(2)第一次使用puts函数输出字符串常量时,在该字符串中没有结束符“\0”,所以字符会一直输出到编译器为字符串添加的结束符“\0”为止。

(3)第二次使用puts函数输出字符串常量时,为其添加了两个“\0”。输出的显示结果表明,检测字符时,遇到第一个结束符时便会停止不再输出字符并且进行换行操作。

(4)第三次使用puts函数输出的是字符串指针变量,函数根据变量的值进行输出。因为变量的值中并没有结束符,所以会一直输出字符,直到编译器为其添加的结束字符为止,然后进行换行操作。

(5)改变变量的值,再使用puts函数进行输出变量时,可以看到由于变量的值中有结束符“\0”,所以显示结果到第一个结束符后停止,最后进行换行操作。

4.3.2 字符串输入函数

字符串输入函数使用的是gets函数,作用是将读取的字符串保存在形式参数str变量中,读取过程直到出现新的一行为止。其中新的一行的换行字符将会转换为字符串中的结束符“\0”。gets函数的定义如下:

char *gets(char *str);

在使用gets字符串输入函数前,要为程序加入头文件stdio.h。其中的str字符指针变量为形式参数。例如定义字符数组变量cString,然后使用gets函数获取输入字符的方式如下:

gets(cString);

在上面的代码中,cString变量获取到了字符串,并将最后的换行符转换成了结束符。

【例4.5】 使用字符串输入函数gets获取输入信息。(实例位置:资源包\源码\04\4.5)

图4.5 使用字符串输入函数gets获取输入信息

运行程序,显示效果如图4.5所示。

程序代码如下:

代码分析:

(1)因为要接收输入的字符串,所以要定义一个可以接收字符串的变量。在程序代码中,定义cString为字符数组变量的标识符,有关字符数组的内容将在后面的章节有所介绍,在此处知道此变量可以接收字符串即可。

(2)调用gets函数,其中函数的参数为定义的cString变量。调用该函数时,程序会等待用户输入字符,当用户字符输入完毕按回车键确定时,gets函数获取字符结束。

(3)使用puts字符串输出函数,将获取后的字符串进行输出。

4.4 格式输出函数

视频讲解

动图演示

前面章节中的实例常常使用格式输入/输出函数,即scanf函数和printf函数。其中,printf函数就是格式输出使用的函数,也称为格式输出函数。

printf函数的作用是向终端(输出设备)输出若干任意类型的数据。printf函数的一般格式如下:

printf(格式控制,输出表列);

 格式控制

格式控制是用双引号括起来的字符串,此处也称为转换控制字符串。其中包括两种字符:一种是格式字符,另一种是普通字符。

  •  格式字符是用来进行格式说明的,作用是将输出的数据转换为指定的格式输出。格式字符是以“%”字符开头的。
  •  普通字符是需要原样输出的字符,其中包括双引号内的逗号、空格和换行符等符号。

 输出列表

输出列表中列出的是要进行输出的一些数据,可以是变量或表达式。

例如,要输出一个整型的变量时:

int iInt=10;
printf("this is %d",iInt);

执行上面的语句显示出来的字符是“this is 10”。在格式控制双引号中的字符是“this is %d”,其中的this is字符串是普通字符,而%d是格式字符,表示输出的是后面iInt的数据。

由于printf是函数,那么“格式控制”和“输出列表”这两个位置都是函数的参数,所以printf函数的一般形式也可以表示为:

printf(参数1,参数2,…,参数n);

函数中的每一个参数按照给定的格式和顺序依次输出。例如,显示一个字符型变量和整型变量:

printf("the Int is %d,the Char is %c",iInt,cChar);

表4.1列出了有关printf函数的格式字符。

表4.1 printf函数格式字符

【例4.6】 使用格式输出函数printf。(实例位置:资源包\源码\04\4.6)

在本实例中,使用printf函数对不同类型变量进行输出,对使用printf函数所用的输出格式进行分析理解。

运行程序,显示效果如图4.6所示。

程序代码如下:

图4.6 使用格式输出函数printf

代码分析:

在程序中定义一个整型变量iInt,在printf函数中使用格式字符%d进行输出。字符型变量cChar赋值为'A',在printf函数中使用格式字符%c进行输出字符。格式字符%f是用来输出实型变量的数值。在最后一个printf输出函数中,可以看到使用%s将一个字符串进行输出,字符串不包括双引号。

另外,在格式说明中,在%符号和上述格式字符间可以插入附加符号,如表4.2所示。

表4.2 printf的附加格式说明字符

注意

在用printf函数时,除了X、E、G外其他格式字符必须用小写字母,如%d不能写成%D。

如果想输出“%”符号,在格式控制处使用%%进行输出即可。

【例4.7】 在printf函数中使用附加符号。(实例位置:资源包\源码\04\4.7)

在本实例中,使用printf函数的附加格式说明字符,对输出的数据进行更为精准的格式设计。

运行程序,显示效果如图4.7所示。

程序代码如下:

图4.7 在printf函数中使用附加符号

代码分析:

(1)在程序代码中,定义的长整型变量在使用printf函数对其进行输出时,应该在%d格式字符中添加l字符,继而输出长整型变量。

(2)%s用来输出一个字符串的格式字符,在结果中可以看到输出了字符串“LOVE”。

(3)%10s为格式%ms,表示输出字符串占m列,如果字符串本身长度大于m,则突破m的限制,将字符串全部输出。若字符串小于m,则用空格进行左补齐。可以看到在字符串“LOVE”前后6个空格。

(4)%-10s格式为%-ms,表示如果字符串长度小于m,则在m列范围内,字符串向左靠,右补空格。

(5)%10.3s格式为%m.ns,表示输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的右侧,左补空格。

(6)%-10.3s格式为%-m.ns,其中m、n含义同上,n个字符输出在m列范围内的左侧,右补空格。如果n>m,则m自动取n值,即保证n个字符正常输出。

4.5 格式输入函数

视频讲解

与格式输出函数printf相对应的是scanf格式输入函数。该函数的功能是可以指定固定的格式,并且按照指定的格式进行接收用户在键盘上输入的数据,最后将数据存储在指定的变量中。

scanf函数的一般格式如下:

scanf(格式控制,地址列表);

通过scanf函数的一般格式可以看出,参数位置中的格式控制与printf函数相同。例如%d表示十进制的整型,%c表示单字符。而地址列表中,此处应该给出用来接收数据的变量的地址。例如得到一个整型数据的操作:

在上面的代码中,“&”符号表示取iInt变量的地址,所以不用关心变量的地址具体是多少,只要像代码中一样,在变量的标识符前加“&”符号,表示的就是取变量的地址。

注意

在编写程序时,读者朋友们要注意的是,在scanf函数参数的地址列表位置处,使用的一定要是变量的地址,而不是变量的标识符,否则编译器会提示错误。

表4.3列出了有关scanf函数中使用的格式字符。

表4.3 scanf函数格式字符

说明

格式字符%s的功能用来输入字符串。将字符串送到一个字符数组中,在输入时以非空白字符开始,以第一个空白字符结束。字符串以串结束标志“\0”作为最后一个字符。

【例4.8】 使用scanf格式输入函数得到用户输入的数据。(实例位置:资源包\源码\04\4.8)

在本实例中,利用scanf函数得到用户输入的两个整型数据,因为scanf函数只能用来进行输入操作,所以在屏幕上显示信息则使用显示函数。

运行程序,显示效果如图4.8所示。

程序代码如下:

图4.8 使用scanf格式输入函数得到用户输入的数据

代码分析:

(1)为了能接受用户输入的整型数据,在程序代码中定义了两个整型变量iInt1和iInt2。

(2)因为scanf函数只能用来接收用户的数据,而不能显示信息。先使用puts函数输出信息提示的一段字符。puts函数在输出字符串之后会自动进行换行,这样就省去使用换行符。

(3)调用scanf格式输入函数,在函数参数中可以看到,在格式控制的位置使用双引号将格式字符包括,%d表示输入的是十进制的整数。在参数中的地址列表位置,使用&符号表示变量的地址。

(4)此时变量iInt1和iInt2已经得到了用户输入的数据,调用printf函数将变量进行输出,这里要注意区分的是printf函数使用的是变量的标识符,而不是变量的地址。scanf函数使用的是变量的地址,而不是变量的标识符。

说明

程序是怎样将输入的内容分别保存到两个指定的变量中的呢?原来scanf函数使用空白字符来进行分隔输入的数据,这些空白字符包括空格、换行、制表符(tab)。例如在本程序中,使用换行作为空白字符。

在printf函数中除了有格式字符,还有附加格式的更为具体的说明,相对应的,scanf函数中也有附加格式的更为具体的说明,如表4.4所示。

表4.4 scanf函数的附加格式

【例4.9】 使用附加格式进行说明scanf函数的格式输入。(实例位置:资源包\源码\04\4.9)

在本实例中,将所有scanf函数的附加格式都进行格式输入的说明,通过对比输入前后的结果,进行观察其附加格式的效果。

运行程序,显示效果如图4.9所示。

图4.9 使用附加格式进行说明scanf函数的格式输入

程序代码如下:

代码分析:

(1)为了在程序中使scanf函数能接收数据,在程序代码中定义所使用的变量。为了演示不同格式的情况,定义变量的类型有长整型、短整型和字符数组。

(2)使用printf函数显示一串字符,提示输入的数据为长整型,调用scanf函数使变量iLong得到用户输入的数据。在scanf函数的格式控制部分,其中格式字符使用l附加格式表示的为长整型。

(3)再使用printf函数显示数据提示,提示输入的数据为短整型。调用scanf函数时,使用附加格式字符h表示短整型。

(4)使用格式字符*的作用是使指定的输入项在读入后不赋给相应的变量,在代码中分析这句话的含义就是,第一个%d是输入iNumber1变量,第二个%d是输入iNumber2变量,但是在第二个%d前有一个*附加格式说明字符,这样第二个输入的值被忽略,也就是说iNumber2变量不保存相应输入的值。

(5)%s是用来表示字符串的格式字符,将一个数n(整数)放入到%s中间,这样就指定了数据的宽度。在程序中,scanf函数中指定的数据宽度为3,那么在输入一个字符串时,只是接收前3个字符。

(6)最后利用printf函数将输入得到的数据进行输出。

4.6 顺序程序设计应用

视频讲解

本节将介绍几个顺序程序设计的实例,使读者对本章所讲的内容进行巩固、加深印象。

【例4.10】 计算圆的面积。(实例位置:资源包\源码\04\4.10)

在本实例中,定义单精度浮点型变量,为其赋值为圆周率的值。得到用户输入的数据进行计算,最后将计算的结果进行输出。

运行程序,显示效果如图4.10所示。

程序代码如下:

代码分析:

(1)定义单精度浮点型Pie表示圆周率,在常量3.14后面加上f表示单精度类型。变量fArea表示的是圆的面积,变量fRadius表示的是圆的半径。

(2)根据puts函数输出的程序提示信息,使用scanf函数获取输入半径的数据,将输入的数据保存在变量fRadius中。

(3)圆的面积=圆的半径的平方×圆周率。运用公式,将变量放入其中计算圆的面积,最后使用printf函数将结果输出。在printf函数中可以看到%.2f格式关键字,其中的.2表示的是取小数点后两位。

【例4.11】 将大写字母转换成小写字母。(实例位置:资源包\源码\04\4.11)

在本实例中,要将一个输入的大写字符转换成小写字符,这需要对ASCII码的关系有所了解。将大写字符转换成小写字符的方法就是将大写字符的ASCII码转换成小写字符的ASCII码即可。

运行程序,显示效果如图4.11所示。

图4.10 计算圆的面积

图4.11 将大写字母转换成小写字母

程序代码如下:

代码分析:

(1)为了将大写字符转换为小写字符,要为其定义变量进行保存。cBig表示要存储字符的字符变量,而cSmall表示要转换成的小写字符。

(2)通过信息提示,用户输入字符。因为只要得到一个输入的字符即可,所以在此处使用getchar函数就可以满足的程序要求。

(3)大写字符与小写字符的ASCII码值相差32。例如字符A的ASCII值为65,a的ASCII值为97,所以如果要将一个大写字符转换成小写字符,那么就将大写字符的ASCII值加上32即可。

(4)字符变量cSmall得到转换的小写字符后,利用printf格式输出函数将字符进行输出,其中使用的格式字符为%c。

4.7 实战

视频讲解

4.7.1 将输入的小写字符转换为大写字符

在C语言中是区分大小写的,利用ASCII码中大写字符和小写字符之间的差值是32的特性,可以实现将小写字符转换为大写字符,在小写字符的ASCII码基础上减去32,就得到了大写字符。运行程序,输入一个小写字符,按回车键以后,程序即可将该字符转换为大写字符,程序运行效果如图4.12所示。(实例位置:资源包\源码\04\实战\01)

图4.12 将输入的小写字符转化为大写字符

4.7.2 用*号输出图案

编程实现用*绘制MR的图案,运行结果如图4.13所示。(实例位置:资源包\源码\04\实战\02)

图4.13 绘制MR图案

4.7.3 输出3×3的矩阵

编程实现显示一个3×3矩阵。具体要求如下:从键盘中任意输入9个数,将由这9个数组成的3×3矩阵输出在屏幕上。运行结果如图4.14所示。(实例位置:资源包\源码\04\实战\03)

图4.14 输出3×3矩阵

4.7.4 输出一个字符的前驱字符

字符在内存中以ASCII码的形式存放,也就是实际存储的是整型数据,因此可以进行运算。本实例利用字符的运算来求字符的前驱字符。(实例位置:资源包\源码\04\实战\04)

运行程序,输入一个字符,求出它的前驱字符,效果如图4.15所示。

图4.15 输出一个字符的前驱字符

4.7.5 根据输入判断能否组成三角形

以下程序根据输入的三角形的三边判断是否能组成三角形。运行结果如图4.16所示。(实例位置:资源包\源码\04\实战\05)

图4.16 能否组成三角形

提示

做本实例之前必须知道三角形的一些相关内容,例如,如何判断输入的三边是否能组成三角形。当从键盘中输入三边,只需判断这3条边中任意的两边之和是否大于第三边,如果大于说明能够组成三角形,否则说明不能组成三角形。