2.6 数据的输入与输出
在用户与计算机进行交互的过程中,数据输入与输出是必不可少的操作过程。计算机需要通过输入获取用户的操作指令,并通过输出显示操作结果。本节将介绍数据输入与输出的相关内容。
2.6.1 C++中的流
C++中,数据的输入和输出发生在标准输入/输出设备(即键盘和显示器)、外部存储介质(即磁盘文件),以及内存空间之间。因此,对键盘和显示器的输入/输出简称“标准I/O”,对磁盘文件的输入/输出简称“文件I/O”,对内存空间的输入/输出简称“串I/O”。
C++把数据之间的这种传输操作称为“流”,意思是数据传输过程像水一样从一个地方流到另一个地方,实现输入的为输入流,实现输出的为输出流。流既可以表示数据从内存传送到某个载体或设备中,也可以表示数据从某个载体或设备传送到内存缓冲区中。程序用流统一对各种计算机设备和文件进行操作,使程序与设备、文件无关,提高了程序设计的通用性和灵活性。
C++定义了ios基类,以及由其派生的输入流类istream和输出流类ostream。标准I/O操作有4个类对象,分别是cin、cout、cerr和clog。其中,cin代表标准输入设备(即键盘),也称cin流或标准输入流;cout代表标准输出设备(即显示器),也称cout流或标准输出流。当进行键盘输入操作时,使用cin流;当进行显示器输出操作时,使用cout流;当进行错误信息输出操作时,使用cerr流或clog流。
C++数据流通过重载运算符“>>”和“<<”执行输入和输出操作。输出操作使用左移运算符“<<”向流中插入一个字符序列,输入操作使用右移运算符“>>”从流中提取一个字符序列。
1.cout语句
cout语句的一般格式为:
cout<<表达式1<<表达式2<<…<<表达式n;
cout代表显示器,执行cout << x操作就相当于把x的值输出到显示器。
先把x的值输出到显示器屏幕上,在当前屏幕光标位置显示出来,然后cout流恢复到等待输出的状态,以便继续通过插入操作输出下一个值。当使用插入操作向一个流输出某个值后,再输出下一个值时将被放在上一个值的后面,所以为了让流中前后两个值分开,可以在输出一个值后接着输出一个空格,或一个换行符,或其他需要的字符或字符串。
一个cout语句可以分写成若干行。例如,下面的语句:
cout<< "Hello World!" <<endl;
可以简单地写成多行:
也可写成多个cout语句:
2.cin语句
cin语句的一般格式为:
cin>>变量1>>变量2>>…>>变量n;
cin代表键盘,执行cin>>x操作就相当于把键盘输入的数据赋给变量x。
通过键盘输入数据时,只有输入完数据并按下Enter键后,系统才会把该行数据存入键盘缓冲区,供cin流顺序读取给变量。另外,从键盘上输入的每个数据之间必须用空格或Enter键分开,因为cin为一个变量读入数据时是以空格或Enter键作为其结束标志的。
当cin>>x操作中的x为字符指针类型时,则要求从键盘的输入中读取一个字符串,并把它赋值给x指向的存储空间。若x没有事先指向一个允许写入信息的存储空间,则无法完成输入操作。另外,从键盘上输入的字符串,其两边不能带有双引号定界符,若有则只作为双引号字符看待。对于输入的字符也是如此,不能带有单引号定界符。
例如,下面的代码可将用户输入的数打印出来。其中,endl用于向流的末尾部位加入换行符。
【实例2.2】默写王之涣的《登鹳雀楼》。(实例位置:资源包\TM\sl\2\2)
使用cout向控制台输出唐朝诗人王之涣的《登鹳雀楼》,具体代码如下:
运行程序,将向控制台屏幕输出诗句,效果如图2.6所示。
图2.6 向控制台屏幕输出诗句
2.6.2 格式化输出
1.流输出(cout)
cout是输出流类ostream的对象,通过其中的成员函数可对数据进行格式化输出,如表2.6和表2.7所示。
表2.6 ostream类的成员函数
表2.7 格式化常量
这些成员函数使用时,前面要加上cout对象名,如cout.setf(ios::left)、cout.width(5)等。另外,可以同时设置多种格式,不同格式间用“|”连接。例如,数据输出时要求左对齐且字母大写,格式应为cout.setf(ios::left|ios::uppercase)。
另外,C++标准库提供的iomanip.h头文件中包含了大量的格式控制符,如表2.8所示,可以直接使用它们进行数据格式化输出,更加简单、快捷。仔细观察,读者会发现这些格式控制符和表2.7中的格式化常量非常相似,但可设置的格式更多。
表2.8 C++格式控制符
【实例2.3】变幻莫测的整数。(实例位置:资源包\TM\sl\2\3)
本实例中,定义一个整型变量并赋值,利用不同形式输出整型,具体代码如下:
程序运行结果如图2.7所示。
【实例2.4】十六进制与十进制转换。(实例位置:资源包\TM\sl\2\4)
本实例中,定义两个整型变量,一个为十六进制整数,另一个为十进制整数。利用cout输出第一个变量的十进制、十六进制形式,第二个变量的小写十六进制和大写十六进制形式。代码如下:
程序运行结果如图2.8所示。
图2.7 整数输出
图2.8 十进制和十六进制转换
【实例2.5】控制输出精确度。(实例位置:资源包\TM\sl\2\5)
本实例中,定义一个整型变量并赋值,定义一个双精度变量并赋值,利用cout输出这两个不同精度的格式,具体代码如下:
程序运行结果如图2.9所示。
【实例2.6】千变万化的小数。(实例位置:资源包\TM\sl\2\6)
本实例中,定义两个单精度类型,用cout输出不同长度的小数,具体代码如下:
程序运行结果如图2.10所示。
图2.9 控制输出精确度
图2.10 流输出小数控制
2.printf()函数输出
C++中保留了C语言的输出函数printf(),使用它可将任意数量、类型的数据输出到屏幕中。printf()函数的声明形式如下:
printf("[控制格式]... [控制格式]...",数值列表);
其中,“数值列表”为待输出数值,可以是多个数值,相邻数值间用逗号隔开;“控制格式”表示数值输出的格式,其数量与待输出数值一致,并一一对应。
控制格式的以“%+特定字符”,形式如下:
%[*][域宽][长度]类型
其中,“*”代表可以使用占位符;“域宽”表示输出长度,如果输出内容没有域宽长,用占位符占位;如果比域宽长,按实际内容输出,以适应域宽;“长度”决定输出内容的长度。例如,%d表示以整型格式输出数据,%c表示以字符格式输出数据。
常见的格式输出类型及输出方式如表2.9所示。
表2.9 printf()函数常见格式输出类型
【实例2.7】整数的格式控制输出。(实例位置:资源包\TM\sl\2\7)
本实例中,使用printf()函数输出整型数,在格式控制时分别以空格和“0”为占位符。代码如下:
程序运行结果如图2.11所示。
【实例2.8】字符串的格式控制输出。(实例位置:资源包\TM\sl\2\8)
本实例中,定义字符型指针(这里不用理会,第7章中会详细介绍)保存字符串"helloworld",利用printf()函数输出,体会不同格式控制下的输出差异。代码如下:
程序运行结果如图2.12所示。
图2.11 整型数格式输出
图2.12 字符串格式输出
【实例2.9】浮点数的格式控制输出。(实例位置:资源包\TM\sl\2\9)
本实例中,定义单精度浮点数和双精度浮点数,利用printf()函数输出,体会不同格式控制下的输出差异。代码如下:
程序运行结果如图2.13所示。
【实例2.10】科学计数法输出。(实例位置:资源包\TM\sl\2\10)
本实例中,利用printf()函数和格式控制符%e,用科学计数法输出小数。代码如下:
程序运行结果如图2.14所示。
图2.13 浮点数格式输出
图2.14 科学计数法输出
误区警示
%x、%X、%#x、%#X的区别:%x表示输出字母小写形式,%X表示输出字母大写形式,#表示输出标准十六进制形式。建议添加“#”,否则当输出的十六进制正好没有字母时,会被误认为是一个十进制数。
编程训练(答案位置:资源包\TM\sl\2\编程训练\)
【训练3】控制台输出汉字 使用cout向控制台输出汉字“明日科技”。
【训练4】地球的年龄有多大 地球的年龄约为45.5亿年,用科学计数法输出地球的年龄。