C++ primer plus 第17 章 输入、输出和文件C++输入和输出概述

C++ primer plus 第17 章 输入、输出和文件C++输入和输出概述

C++ primer plus 第17 章 输入、输出和文件C++输入和输出概述


C++ primer plus 第17 章 输入、输出和文件C++输入和输出概述

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

17.1 C++输入和输出概述

多数计算机语言的输入和输出是以语言本身为基础实现的。例如,从诸如 BASIC和Pascal 等语言的关键字列表中可知,PRINT语句、Witein 语句以及其他类似的语句都是语言词汇表的组成部分,但C和C++都
没有将输入和输出建立在语言中。这两种语言的关键字包括for和i,但不包括与IO有关的内容。C语言最初把 IO留给了编译器实现人员。这样做的一个原因是为了让实现人员能够自由的设计 IO函数,使之最适合于目标计算机的硬件要求。实际上,多数实现人员都把O建立在最初为UNIX 环境开发的库函数的基础之上。ANSIC正式承认这个I/O软件包时,将其称为标准输入/输出包,并将其作为标准C库不可或缺的组成部分。C++也认可这个软件包,因此如果熟悉stdioh文件中声明的C函数系列,则可以在 C++程序中使用它们(较新的实现使用头文件cstdio来支持这些函数)。然而,C++依赖于 C++的 IO 解决方案,而不是C语言的 IO 解决方案,前者是在头文件iostream(以前为 iostream.h)和 fstream(以前为fstream.h)中定义一组类。这个类库不是正式语言定义的组成部分(cin和istream 不是关键字);毕竟计算机语言定义了如何工作(例如如何创建类)的规则,但没有定义应按照这些规则创建哪些东西。
然而,正如C实现自带了一个标准函数库一样,C++也自带了一个标准类库。首先,标准类库是一个非正式的标准,只是由头文件iostream和fstream中定义的类组成。ANSI/ISOC++委员会决定把这个类正式作为一个标准类库,并添加其他一些标准类,如第16章讨论的那些类。本章将讨论标准C++ IO。但首先看一看C++O的概念框架

17.1.1 流和缓冲区

C++程序把输入和输出看作字节流。输入时,程序从输入流中抽取字节:输出时,程序将字节插入到输出流中。对于面向文本的程序,每个字节代表一个字符,更通俗地说,字节可以构成字符或数值数据的二进制表示。输入流中的字节可能来自键盘,也可能来自存储设备(如硬盘)或其他程序。同样,输出流中的字节可以流向屏幕、打印机、存储设备或其他程序。流充当了程序和流源或流目标之间的桥梁。这使得 C++程序可以以相同的方式对待来自键盘的输入和来自文件的输入。C+程序只是检查字节流,而不需要知道字节来自何方。同理,通过使用流,C++程序处理输出的方式将独立于其去向。因此管理输入包含两步:将流与输入去向的程序关联起来。将流与文件连接起来。
换句话说,输入流需要两个连接,每端各一个。文件端部连接提供了流的来源,程序端连接将流的流出部分转储到程序中(文件端连接可以是文件,也可以是设备,如键盘)。同样,对输出的管理包括将输出流连接到程序以及将输出目标与流关联起来。这就像将字节(而不是水)引入到水管中(参见图17.1)。
在这里插入图片描述
通常,通过使用缓冲区可以更高效地处理输入和输出。缓冲区是用作中介的内存块,它是将信息从设备传输到程序或从程序传输给设备的临时存储工具。通常,像磁盘驱动器这样的设备以 512字节(或更多)的块为单位来传输信息,而程序通常每次只能处理一个字节的信息。缓冲区帮助匹配这两种不同的信息传输速率。例如,假设程序要计算记录在硬盘文件中的金额。程序可以从文件中读取一个字符,处理它,再从文件中读取下一个字符,再处理,依此类推。从磁盘文件中每次读取一个字符需要大量的硬件活动,速度非常慢。缓冲方法则从磁盘上读取大量信息,将这些信息存储在缓冲区中,然后每次从缓冲区里读取一个字节。因为从内存中读取单个字节的速度比从硬盘上读取快很多,所以这种方法更快,也更方便。当然,到达缓冲区尾部后,程序将从磁盘上读取另一块数据。这种原理与水库在暴风雨中收集儿兆加仑流量的水,然后以比较文明的速度给您家里供水是一样的(见图17.2)。输出时,程序首先填满缓冲区,然后把整块数据传输给硬盘,并清空缓冲区,以备下一批输出使用。这被称为刷新缓冲区(fushing thebufcr)。
键盘输入每次提供一个字符,因此在这种情况下,程序无需缓冲区来帮助匹配不同的数据传输速率。然而,对键盘输入进行缓冲可以让用户在将输入传输给程序之前返回并更正。C++程序通常在用户按下回车键时刷新输入缓冲区。这是为什么本书的例子没有一开始就处理输入,而是等到用户按下回车键后再处理的原因。对于屏幕输出,C++程序通常在用户发送换行符时刷新输出缓冲区。程序也可能会在其他情况下刷新输入,例如输入即将到来时,这取决于实现。也就是说,当程序到达输入语句时,它将刷新输出缓冲区中当前所有的输出。与ANSIC一致的C++实现是这样工作的。

17.1.2 流、缓冲区和 iostream 文件

管理流和缓冲区的工作有点复杂,但iostream(以前为iostream.h)文件中包含一些专门设计用来实现、
管理流和缓冲区的类。C++98版本C++O定义了一些类模板,以支持char和wchart数据:C++11添加了char16t和 char32t具体化。通过使用typedef工具,C++使得这些模板 char 具体化能够模仿传统的非模板 O实现。下面是其中的一些类(见图17.3):
在这里插入图片描述

  • streambuf类为缓冲区提供了内存,并提供了用于填充缓冲区、访问缓冲区内容、刷新缓冲区和管理缓冲区内存的类方法:
  • ios base 类表示流的一般特征,如是否可读取、是二进制流还是文本流等:
  • ios 类基于ios base,其中包括了一个指向streambuf对象的指针成员:
  • ostream 类是从ios 类派生而来的,提供了输出方法:
  • istream 类也是从 ios 类派生而来的,提供了输入方法:
  • iostream 类是基于istream 和 ostream 类的,因此继承了输入方法和输出方法。
    要使用这些工具,必须使用适当的类对象。例如,使用ostream对象(如cout)来处理输出。创建这样的对象将打开一个流,自动创建缓冲区,并将其与流关联起来,同时使得能够使用类成员函数。

重定义 I/0

`ISO/ANSI标准 C++98对I/O作了两方面的修订。首先是从 ostreamh到ostrcam的变化,用 ostream 将类放到 std 名称空间中。其次,I/0类被重新编写。为成为国际语言,C++必须能够处理需要 16 位的国际字符集或更宽的字符类型。因此,该语言在传统的8位char(“窄”)类型的基础上添加了 wchar t(“宽”)宇符类型;而C++11添加了类型char16t和char32t。每种类型都需要有自己的IO工具。标准委员会并没有开发两套(现在为4套)独立的类,而是开发了1套 I/0类模板,其中包括 basic istrcam<charT,lraits>和 basic ostrcam<charT,traits>。traits模板是一个模板类,为字符类型定义了具体特性,如如何比较字符是否相等以及字符的 EOF值等。该C++11标准提供了I/O的 char 和 wchar t具体化。例如,istream和ostream都是char具体化的typedef。同样,wistream和 wostrcam 都是 wchar t具体化。例如,wcout对象用于输出宽字符流。头文件ostream中包含了这些定义。ios 基类中的一些独立于类型的信息被移动到新的ios basc 类中,这包括各种格式化常量、价如10s:.fixed(现在为ios base::fixed)。另外,ios base还包含了一些老式ios 中没有的选项。
C++的 iostream 类库管理了很多细节。例如,在程序中包含iostream 文件将自动创建8个流对象(4个用于窄字符流,4个用于宽字符流)。

  • cin 对象对应于标准输入流。在默认情况下,这个流被关联到标准输入设备(通常为键盘)。wcin对象与此类似,但处理的是 wchart类型。

  • cout对象与标准输出流相对应。在默认情况下,这个流被关联到标准输出设备(通常为显示器)。
    wcout 对象与此类似,但处理的是wchart类型。

  • cem 对象与标准错误流相对应,可用于显示错误消息。在默认情况下,这个流被关联到标准输出设备(通常为显示器)。这个流没有被缓冲,这意味着信息将被直接发送给屏幕,而不会等到缓冲区填满或新的换行符。wcer对象与此类似,但处理的是wchart类型。

  • clog对象也对应着标准错误流。在默认情况下,这个流被关联到标准输出设备(通常为显示器)。这个流被缓冲。wclog对象与此类似,但处理的是wchart类型。对象代表流–这意味着什么呢?当iostream 文件为程序声明一个cout 对象时,该对象将包含存储了与输出有关的信息的数据成员,如显示数据时使用的字段宽度、小数位数、显示整数时采用的计数方法以及描述用来处理输出流的缓冲区的streambuf对象的地址。下面的语句通过指向的streambuf对象将字符串“Bjarmafree”中的字符放到cout 管理的缓冲区中:

cout << "Biarne free";

ostream 类定义了上述语句中使用的 operator<<()函数,ostream 类还支持cout 数据成员以及其他大最的类方法(如本章稍后将讨论的那些方法)。另外,C++注意到,来自缓冲区的输出被导引到标准输出(通常是显示器,由操作系统提供)。总之,流的一端与程序相连,另一端与标准输出相连,cout 对象凭借 streambuf对象的帮助,管理着流中的字节流。

17.1.3 重定向

标准输入和输出流通常连接着键盘和屏幕。但很多操作系统(包括UNIX、Linux和 Windows)都支持重定向,这个工具使得能够改变标准输入和标准输出。例如,假设有一个名为counter.exe 的、可执行的Windows命令提示符 C++程序,它能够计算输入中的字符数,并报告结果(在大多数 Windows 系统中,可以选择“开始”>“程序”,再单击“命令提示符”来打开命令提示符窗口)。该程序的运行情况如下:

C>counter
Hello
and goodbye!
Control-2 << simulated end-offle
Input contained 19 characters.
C>

其中的输入来自键盘,输出的被显示到屏幕上。
通过输入重定向(<)和输出重定向(>),可以使用上述程序计算文件oklahoma中的字符数,并将结果放到cow ct 文件中:

cow_cnt file:
C>counter <oklahoma >cow cntC>

命令行中的<oklahoma将标准输入与 oklahoma文件关联起来,使 cin 从该文件(而不是键盘)读取输入。换句话说,操作系统改变了输入流的流入端连接,而流出端仍然与程序相连。命令行中的>cow_cnt将标准输出与cow_cnt 文件关联起来,导致cout 将输出发送给文件(而不是屏幕)。也就是说,操作系统改变了输出流的流出端连接,而流入端仍与程序相连。DOS、Windows命令提示符模式、Linux 和 UNIX 能门动识别这种重定向语法(除早期的DOS外,其他操作系统都允许在重定向运算符与文件名之间加上可选的空格)。cout代表的标准输出流是程序输出的常用通道。标准错误流(由 cem 和 clog 代表)用于程序的错误消息。默认情况下,这3个对象都被发送给显示器。但对标准输出重定向并不会影响cen或clog,因此,如果使用其中一个对象来打印错误消息,程序将在屏幕上显示错误消息,即使常规的cout 输出被重定向到其他地方。例如,请看下面的代码片段:

if (success)
std::cout <<"Here come the goodies!\n";
else
{
std::cerr <<"Something horrible has happened.\n";
exit(1);
}

如果重定向没有起作用,则选定的消息都将被显示在屏幕上。然而,如果程序输出被重定向到一个文件,则第一条消息(如果被选定)将被发送到文件中,而第二条消息(如果被选定)将被发送到屏幕。顺便说一句,有些操作系统也允许对标准错误进行重定向。例如,在UNIX和Limux 中,运算符 2>重定向标准错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值