![C++从入门到精通(第5版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/641/47216641/b_47216641.jpg)
2.5 数据输入与输出
在用户与计算机进行交互的过程中,数据输入与输出是必不可少的操作过程。计算机需要通过输入获取用户的操作指令,并通过输出显示操作结果。本节将介绍数据输入与输出的相关内容。
2.5.1 控制台屏幕
在NT内核的Windows操作系统中为保留DOS系统的风格,提供了控制台程序,单击系统的“开始”→“运行”命令,运行cmd.exe程序,可以启动控制台。在控制台中可以运行DIR、CD、DELETE等DOS系统中的文件操作命令,也可以启动Windows程序。控制台屏幕如图2.7所示。
使用Visual C++ 6.0创建的控制台程序都将运算结果输出到如图2.7所示的控制台屏幕上,它是程序显示输出结果的地方。
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P41_8176.jpg?sign=1739250444-8bTYktNRBRPq6p5ffQUBEO2z5LHca7Fv-0-e2221801438279117a30c8ba0cb8c1bd)
图2.7 控制台屏幕
2.5.2 C++语言中的流
在C++语言中,数据的输入和输出发生在标准输入/输出设备(键盘、显示器)、外部存储介质(磁盘)和内存的存储空间。对标准输入/输出设备的输入/输出简称标准I/O,对在外存磁盘上文件的输入/输出简称文件I/O,对内存中指定的字符串存储空间的输入/输出简称串I/O。
C++语言中把数据之间的传输操作称为流。C++中的流既可以表示数据从内存传送到某个载体或设备中,即输出流;也可以表示数据从某个载体或设备传送到内存缓冲区变量中,即输入流。C++中所有流都是相同的,但文件可以不同(文件流参见第16章)。使用流以后,程序用流统一对各种计算机设备和文件进行操作,使程序与设备、文件无关,从而提高了程序设计的通用性和灵活性。
C++语言定义了I/O类库供用户使用,标准I/O操作有4个类对象,分别是cin、cout、cerr和clog。其中cin代表标准输入设备键盘,也称cin流或标准输入流。cout代表标准输出显示器,也称cout流或标准输出流,当进行键盘输入操作时使用cin流,当进行显示器输出操作时使用cout流,当进行错误信息输出操作时使用cerr流或clog流。
C++的流通过重载运算符“<<”和“>>”执行输入和输出操作。输出操作是向流中插入一个字符序列,因此,在流操作中,将左移运算符“<<”称为插入运算符。输入操作是从流中提取一个字符序列,因此,将右移运算符“>>”称为提取运算符。
1.cout语句的一般格式
cout<<表达式1<<表达式2<<…<<表达式n;
cout代表显示器,执行cout << x操作就相当于把x的值输出到显示器。
先把x的值输出到显示器屏幕上,在当前屏幕光标位置显示出来,然后cout流恢复到等待输出的状态,以便继续通过插入操作符输出下一个值。当使用插入操作符向一个流输出一个值后,再输出下一个值时将被放在上一个值的后面,所以为了让流中前后两个值分开,可以在输出一个值后接着输出一个空格,或一个换行符,或其他需要的字符或字符串。
一个cout语句可以分写成若干行,例如:
cout<< "Hello World!" <<endl;
可以写成:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P42_16707.jpg?sign=1739250444-Y7H9UnftoVdpvsO3re62btkOHIrXjyOt-0-f4a380454f9bcd395ade19a5d074c89e)
也可写成多个cout语句:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P42_16708.jpg?sign=1739250444-AQOtPqs4RaKGWRHxOhqk2mKKPgXsNyIZ-0-3c9cbb53251277a0fa4a5575f430b8b1)
以上3种情况的输出均正确。
2.cin语句的一般格式
cin>>变量1>>变量2>>…>>变量n;
cin代表键盘,执行cin>>x操作就相当于把键盘输入的数据赋值给变量。
当从键盘上输入数据时,只有当输入完数据并按下Enter键后,系统才把该行数据存入键盘缓冲区,供cin流顺序读取给变量。另外,从键盘上输入的每个数据之间必须用空格或Enter键分开,因为cin为一个变量读入数据时是以空格或Enter键作为其结束标志的。
当cin>>x操作中的x为字符指针类型时,则要求从键盘的输入中读取一个字符串,并把它赋值给x指向的存储空间,若x没有事先指向一个允许写入信息的存储空间,则无法完成输入操作。另外,从键盘上输入的字符串,其两边不能带有双引号定界符,若有则只作为双引号字符看待。对于输入的字符也是如此,不能带有单引号定界符。
cin相当于C库函数中的scanf,作用是将用户的输入赋值给变量。例如,下面的代码可将用户输入的数打印出来。
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P42_16709.jpg?sign=1739250444-G2Ms0HWYZJM7sujH8iVtLL87HqGhJJ8U-0-b99a595974247a85c1a14ecfd81396c3)
【实例2.3】 默写王之涣的《登鹳雀楼》。(实例位置:资源包\TM\sl\2\3)
使用cout向控制台输出唐朝诗人王之涣的《登鹳雀楼》,具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P42_16834.jpg?sign=1739250444-YloCdjKT6o62zeAkZ5LzXQSkzYdIl210-0-e23a074f6d30633dc9f490ef20701e19)
运行程序,将向控制台屏幕输出诗句,效果如图2.8所示。其中,endl用于向流的末尾部位加入换行符。
2.5.3 流操作的控制
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P43_8369.jpg?sign=1739250444-YRnTV3U0ZbOaPWgpD8Wt7gb2Xv9nBTi0-0-0f005990cce3612553aa67682e52c5f7)
图2.8 向控制台屏幕输出诗句
在头文件iomanip.h中定义了一些控制流输出格式的函数,默认情况下整型数按十进制形式输出,也可以通过hex将其设置为十六进制输出。
(1)long setf(long f); 根据参数f设置相应的格式标志,返回此前的设置。该参数f对应的实参为无名枚举类型中的枚举常量(又称格式化常量),可以同时使用一个或多个常量,每两个常量之间要用按位或操作符连接。如需要左对齐输出,并使数值中的字母大写,则调用该函数的实参为ios::left|ios::uppercase。
(2)long unsetf(long f); 根据参数f清除相应的格式标志,返回此前的设置。如果要清除此前的左对齐输出设置,恢复默认的右对齐输出设置,则调用该函数的实参为ios::left。
(3)int width(); 返回当前的输出域宽。若返回数值为0,则表明没有为刚才输出的数值设置输出域宽。输出域宽是指输出的值在流中占有的字节数。
(4)int width(int w); 设置下一个数据值的输出域宽为w,返回为输出上一个数据值规定的域宽,若无规定则返回0。注意,此设置不是一直有效,而只是对下一个输出数据有效。
(5)setiosflags(long f); 设置f对应的格式标志,功能与setf(long f)成员函数相同,当然,在输出该操作符后返回的是一个输出流。如果采用标准输出流cout输出,则返回cout。输出每个操作符后都是如此,即返回输出它的流,以便向流中继续插入下一个数据。
(6)resetiosflags(long f); 清除f对应的格式标志,功能与unsetf(long f)成员函数相同。输出后返回一个流。
(7)setfill(char c); 设置填充字符的ASCII码为c的字符。
(8)setprecision(int n); 设置浮点数的输出精度为n。
(9)setw(int w); 设置下一个数据的输出域宽为w。
数据输入/输出的格式控制还有更简便的形式,就是使用头文件iomainip.h中提供的操作符。使用这些操作符不需要调用成员函数,只要把它们作为插入操作符“<<”的输出对象即可。
dec:转换为按十进制输出整数,是默认的输出格式。
oct:转换为按八进制输出整数。
hex:转换为按十六进制输出整数。
ws:从输出流中读取空白字符。
endl:输出换行符\n并刷新流。
ends:输出一个空字符\0。
flush:只刷新一个输出流。
【实例2.4】 控制打印格式。(实例位置:资源包\TM\sl\2\4)
本实例中,定义一个双精度类型的变量并赋值,利用各种格式打印数据,具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P44_16712.jpg?sign=1739250444-hVB0cm5RcyjwW24lpsCJNqlSnsPa8NBF-0-90e6dd38f8b827298e77dbc3ab3a4c23)
程序运行结果如图2.9所示。
【实例2.5】 变幻莫测的整数。(实例位置:资源包\TM\sl\2\5)
本实例中,定义一个整数变量并赋值,利用不同形式输出整型,具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P44_16713.jpg?sign=1739250444-tqTb1pxduuVOLhRfF2DNa53jivWGQwvm-0-802d630bdc75c92583f3812b8e06e084)
程序运行结果如图2.10所示。
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P44_8543.jpg?sign=1739250444-xJxOJJgE7nf02P2wsF1hXKc9bRsaxlnJ-0-2e177b690270c24d6bae672da585c517)
图2.9 控制打印格式
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P44_8544.jpg?sign=1739250444-X3mJzh8NhHDfYSEJOSWid3X52ESdxclw-0-dc6074a14fd7da6876e6caf81b998c84)
图2.10 整数输出
【实例2.6】 十六进制与十进制转换。(实例位置:资源包\TM\sl\2\6)
本实例中,定义两个整型变量,其中一个变量赋值为十六进制,另一个变量赋值为十进制。利用cout输出第一个变量十进制、十六进制,用cout输出第二个变量小写十六进制和大写十六进制。具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P44_16836.jpg?sign=1739250444-smJAawzCC7Dy5CVB0EJsoUfQtiwsI5yR-0-e543cb7a8d8c8141c3e6a781ac8b0073)
程序运行结果如图2.11所示。
【实例2.7】 控制输出精确度。(实例位置:资源包\TM\sl\2\7)
本实例中,定义一个整型变量并赋值,定义一个双精度变量并赋值,利用cout输出这两个不同精度的格式,具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P45_16716.jpg?sign=1739250444-78tVgefByBFNr0JgTj88OMceLCO0QT2O-0-c249a52eea42742c3d851d1ea4368ecf)
程序运行结果如图2.12所示。
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P45_8784.jpg?sign=1739250444-z6I7wexbvuTjXic8XK9aCa2ys2wzGSF1-0-b70041972a1aeb7df3b138cbce316608)
图2.11 输出十进制和十六进制
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P45_8785.jpg?sign=1739250444-Hh5pyH8FA1OoV5JhuY9LqsIT9y8WNu3a-0-211bb102a5dd8474279763f536c4b58c)
图2.12 控制输出精确度
【实例2.8】 千变万化的小数。(实例位置:资源包\TM\sl\2\8)
本实例中,定义两个单精度类型,用cout输出不同长度的小数,具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P46_16717.jpg?sign=1739250444-q9hUrHj0koONrnO0r57f0M344lpGYfOi-0-32c2bf88c869f51179e9dda9cde90454)
程序运行结果如图2.13所示。
C++语言中还保留着C语言的输出函数printf,使用printf可以将任意数量、类型的数据输出到屏幕中。printf函数的声明形式如下:
printf("[控制格式]... [控制格式]...",数值列表);
printf是变参函数,数值列表中可以有多个数值,数值的个数不是确定的,每个数值之间用逗号运算符隔开;控制格式表示数值以哪种格式输出,控制格式的数量要与数值的个数一致,否则程序运行时会产生错误。
控制格式由“%+特定字符”构成,形式如下:
%[*][域宽][长度]类型
“*”代表可以使用占位符,域宽表示输出的长度。如果输出的内容没有域宽长,用占位符占位;如果比域宽长,就按实际内容输出,以适应域宽。长度决定输出内容的长度,例如,%d代表以整型数据格式输出。常见的输出类型如表2.6所示。
表2.6 常见输出类型
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-T46_16719.jpg?sign=1739250444-dc2XTeRddspqFeegzgnA5Z6l5B9et7eV-0-4e285a4da1d49708870e9bdecf79d807)
(1)d格式符,以十进制形式输出整数。
%d:按整型数据的实际长度输出。
%*md:m用于指定输出字段的宽度,如果数据的位数小于m,用*指定的字符占位;如果*未指定用空格占位,若大于m,则按实际位数输出。
%ld:输出长整型数据。
【实例2.9】 printf占位输出形式。(实例位置:资源包\TM\sl\2\9)
本实例中,使用printf格式输出函数,在格式符号中间加0做占位符,具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P47_16720.jpg?sign=1739250444-sv9FOvuDLGBJ1ZfkZzTTjnlkWdvzEO0m-0-9933bff50fe7a33bff995d629a83b79b)
程序运行结果如图2.14所示。
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P47_9015.jpg?sign=1739250444-6FtrdWrkvwOFHqVvOt9PEIQqbKDizujZ-0-86663fe205f5535cad8fc328cb03bd55)
图2.13 流输出小数控制
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P47_9018.jpg?sign=1739250444-aPZEKkYrFtZRstnzanMekKxB8PJktSlc-0-3d57eda416c5e07f7fd398a01be00571)
图2.14 输出占位符
(2)o格式符,以八进制形式输出整数。
%o:按整型数据的实际长度输出。
%*mo:m用于指定输出字段的宽度,如果数据的位数小于m,用*指定的字符占位;如果*未指定用空格占位,若大于m,则按实际位数输出。
%lo:输出长整型数据。
(3)x格式符,以十六进制形式输出整数。
%x:按整型数据的实际长度输出。
%*mx:m用于指定输出字段的宽度,如果数据的位数小于m,用*指定的字符占位;如果*未指定用空格占位,若大于m,则按实际位数输出。
%lx:输出长整型数据。
(4)s格式符,用来输出一个字符串。
%s:将字符串按实际长度输出。
%*ms:输出的字符串占m列,如果字符串本身长度大于m,则突破m的限制,将字符串全部输出;如果*未指定用空格占位,若字符串长度小于m,则左补空格。
%-ms:如果字符串长度小于m,则在m列范围内,字符串向左靠,右补空格。
%m.ns:输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的右侧,左补空格。
%-m.ns:输出长整型数据。输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的左侧,右补空格。
【实例2.10】 截取helloworld。(实例位置:资源包\TM\sl\2\10)
本实例中,定义字符型指针(第7章详细介绍)用来保存字符串,利用printf函数格式输出字符串,代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P48_16721.jpg?sign=1739250444-tyAJiX6WzI4U3lqyLI4yuKOaKIGGUJKt-0-8cc72dc235090c8dc92c80f6f3b949ac)
程序运行结果如图2.15所示。
(5)f格式符,以小数形式输出实型数据。
%f:不指定字段宽度,整数部分全部输出,小数部分输出6位。
%m.nf:输出的数据占m列,其中有n位小数。如果数值长度小于m,则左端补空格。
%-m.nf:输出的数据占m列,其中有n位小数。如果数值长度小于m,则右端补空格。
【实例2.11】 输出格式控制。(实例位置:资源包\TM\sl\2\11)
本实例中,定义一个单精度和一个双精度类型,利用printf格式输出不同形式,具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P48_16722.jpg?sign=1739250444-TyrC8sUTiPVj9SWIscaS1aDfIgv1nLvu-0-0421cc6d2680c798963ad2288f4d63b5)
程序运行结果如图2.16所示。
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P48_9108.jpg?sign=1739250444-PP0I56HCzPCoeXeK9dXgLhIYGvqJNwCN-0-db38a971e554e5338b5c050fc1a3dfd7)
图2.15 输出格式控制字符串输出
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P48_9111.jpg?sign=1739250444-85tbGIp6hNNvQnMZqlm7xYaqKbBDRL7a-0-93d34002ec379f32325ce4eb77aa14e6)
图2.16 输出格式控制
(6)e格式符,以指数形式输出实型数据。
%e:不指定输出数据所占的宽度和小数位数。
%m.ne:输出的数据占m位,其中有n位小数。如果数值长度小于m,则左端补空格。
%-m.ne:输出的数据占m位,其中有n位小数。如果数值长度小于m,则右端补空格。
【实例2.12】 科学计数法输出。(实例位置:资源包\TM\sl\2\12)
本实例中,利用printf格式控制符%e,将小数用科学计数法输出,具体代码如下:
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P48_16723.jpg?sign=1739250444-pe240BcZU2dh7lIiCedyrF3lwOgfk6uY-0-5e64101cf55edf0a7e90121bf33834ca)
程序运行结果如图2.17所示。
![](https://epubservercos.yuewen.com/77E99B/26581282609167606/epubprivate/OEBPS/Images/Figure-P49_9164.jpg?sign=1739250444-JTpF0F3agf3QnKuiGhgCq2Omw2K6I38W-0-62c3add407673794db1b11d141a4b70b)
图2.17 科学计数法输出
误区警示
一定要注意%x(%X、%#x、%#X),因为调试时经常要将内存中的二进制代码输出。这几种形式解释如下:
如果是x,输出的字母就是小写的;如果是X,输出的字母就是大写的;如果加一个“#”就会以标准的十六进制形式输出。建议最好是加一个“#”,否则如果输出的十六进制正好没有字母,就会被误认为是一个十进制数。
编程训练(答案位置:资源包\TM\sl\2\编程训练\)
【训练3】 控制台输出汉字 使用cout向控制台输出汉字“明日科技”。
【训练4】 地球的年龄有多大 地球的年龄约为45.5亿年,用科学计数法输出地球的年龄。