15.2 字符串流
可以通过字符串流将流语义用于string。通过这种方式,可得到一个内存内的流(in memory stream),通过这个流表示文本数据。例如,在一个GUI应用程序中,可能需要用流来构建文本数据,但是不想将文本输出到控制台或文件中,而是想要作为结果显示在GUI元素中,例如消息框和编辑框。另一个例子是,假如想要将一个字符串流作为参数传给不同函数,同时想要维护当前的读位置,这样每一个函数都可以处理流的下一部分。字符串流也非常适于解析文本,因为流内建了标记化的功能。
ostringstream类用于将数据写入string,istringstream用于将数据从一个string中读出。这两个类都定义在<sstream>头文件中。由于ostringstream和istringstream分别继承了来自ostream和istream的同样功能,因此这些类的使用也非常类似。
下面的程序从用户那里请求单词,然后将这些单词输入到一个ostringstream中,通过制表符将单词分开。在程序的最后,整个流通过str()方法转换为一个string对象,并写入控制台。可以通过输入标记"done"来停止标记的输入,或通过按下Control+D(Unix)或Control+Z(Windows)来关闭输入流。
- cout << "Enter tokens. Control+D (Unix) or Control+Z (Windows) to end" << endl;
- ostringstream outStream;
- while (cin) {
- string nextToken;
- cout << "Next token: ";
- cin >> nextToken;
- if (nextToken == "done")
- break;
- outStream << nextToken << "\t";
- }
- cout << "The end result is: " << outStream.str();
-
- 代码取自StringStream\StringStream.cpp
从一个字符串流中读入数据非常类似。下面的函数创建一个Muffin对象,并通过从字符串输入流中读入的数据填充这个对象(参见此前的例子)。流数据格式固定,因此这个函数可以轻松地将数据值转换为对Muffin类的设置方法的调用: - Muffin createMuffin(istringstream& inStream)
- {
- Muffin muffin;
- // Assume data is properly formatted:
- // Description size chips
- string description;
- int size;
- bool hasChips;
- // Read all three values. Note that chips is represented
- // by the strings "true" and "false"
- inStream >> description >> size >> boolalpha >> hasChips;
- muffin.setSize(size);
- muffin.setDescription(description);
- muffin.setHasChocolateChips(hasChips);
- return muffin;
- }
-
- 代码取自Muffin\Muffin.cpp
将一个对象转换为一个"扁平"类型(例如string)的过程通常称为编组(marshall)。将对象保存至磁盘或通过网络发送的时候,编组操作非常有用。
相比于标准C++(www.cppentry.com) string,字符串流最主要的好处是除了数据之外,这个对象还知道从哪里进行下一次读或写操作,这个位置也称为当前位置。根据特定的字符串流的实现,可能还会有性能优势。例如,如果需要将大量字符串串联在一起,使用字符串流的效率可能比反复调用string对象的+=运算符的效率更高。