4.7 字符串输入输出流

字符串输入输出流类直接对内存而不是对文件和标准输出(设备)进行操作。它使用与cin及cout相同的读取和格式化函数来操纵内存中的数据。在早期的计算机中,内存储器是计算机的核心,所以这种功能的类型常常称为内核格式化(in-core formatting)。

字符串流的类名模仿文件流的类名。如果需要创建一个字符串流,并从这个流读取字符,可以创建istringstream。如果需要写字符到字符串流,可以创建ostringstream。所有字符串流类的声明都包含在标准头文件<sstream>中。照例,有一些类模板被添加到输入输出流类层次结构中,如下图所示:

4.7 字符串输入输出流 - 图1

4.7.1 输入字符串流

为了使用流操作从一个字符串中读取数据,需要创建istringstream对象并用字符串初始化这个对象。下面的程序说明了如何使用istringstream对象:

4.7 字符串输入输出流 - 图2

读者可以看到,这是一种将字符串转换为特定类型值的方法,比标准C中的库函数如atof()和atoi()更灵活、更通用,尽管后者对单个字符串的转换效率更高。

在表达式s>>i>>f中,字符串中的第1个数字摘录到i,第2个数字输出到f。因为它依赖于数据的类型进行摘录,所以不是“以空格作为首选界定符的字符集”。例如,当字符串为“1.414 47 This is a test”时,则i提取的值为1,因为输入过程会在小数点处停止。f提取的值为0.414。如果想把一个浮点数分成整数部分和小数部分,则这种方法就很有效。而在其他情况下这似乎是错误的做法。第2个assert()函数判断读出的数据是否发生了错误;这样做比简单地比较两个浮点数是否相等更好。函数epsilon()返回一个在<limits>中定义的常量,代表双精度数字的机器误差,这是在比较两个double型数据时所能得到的最小误差[1]

或许读者已经猜到buf2中的内容不等于剩下的串,只是等于下一个空格字符之前的单词。一般来说,当知道输入流中数据的顺序并把它转换成除字符串之外的数据类型时,最好使用输入输出流提取符。然而,如果想一次性提取一个串中剩余的部分并把它输出到另一个输入输出流中,可以使用程序中所示的函数rdbuf()。

为测试本章早些时候提到的Date提取符,在下面的测试程序中使用输入字符串流:

4.7 字符串输入输出流 - 图3

在main()函数中,将每个字符串作为引用参数依次调用函数testDate(),函数testDate()把参数封装到istringstream对象中,这样就可以测试为Date对象所编写的流提取符了。函数testDate()也对插入符operator<<()进行了测试。

4.7.2 输出字符串流

为了创建输出字符串流,可以构造ostringstream对象,这个类对象可以管理动态字符缓冲区,缓冲区存放要插入的任何字符串。为了将输出结果格式化为string对象,可以调用成员函数str(),举例如下:

4.7 字符串输入输出流 - 图4

4.7 字符串输入输出流 - 图5

这个例子中读取int和float的语句与Istring.cpp中的语句相似。下面是一个输出结果的例子(黑体部分为键盘输入)。

4.7 字符串输入输出流 - 图6

读者可以看到,就像其他的输出流,输出字节到ostringstream对象可以使用一般的格式化工具,如运算符<<和endl。每次调用str()函数都会返回一个新的string对象,所以字符串流内置的stringbuf对象不会被破坏。

在第3章中,给出了一个程序HTMLStripper.cpp,它的作用是删除文本文件中的所有HTML标记及特殊字符。这里给出一种使用字符串流的更优美的版本:

4.7 字符串输入输出流 - 图7

4.7 字符串输入输出流 - 图8

在这个程序中,通过把文件流的rdbuf()调用放到一个ostringstream对象中,最终将整个文件读到一个字符串中。这样搜索HTML文件中的界定符对并将其删除就很容易了,也不必像第3章中的前一版本那样考虑跨越多行的标记。

下面的例子说明了如何使用双向(即,读/写)字符串流:

4.7 字符串输入输出流 - 图9

同前面一样,通过调用seekp()移动写指针,调用seekg()重定位读指针。字符串流比文件流使用起来更容易,因为任何时候都可以从流的读状态切换到写状态或从写状态切换到读状态,但是在这个例子中没有引入这方面的内容。在这个过程中,不需要重定位读指针或写指针,或刷新流。在这个程序中也说明了重载的str()函数,它用一个新字符串替换流中内置的stringbuf。

[1]关于机器双精度数字和浮点数的一般性计算,请参考“标准C库,第三部分”,C/C++用户周刊,1995年3月。也可查阅网页:www.freshsources.com/1995006a.html。