Team LiB
Previous Section Next Section

8.5. String Streams

8.5. 字符串流

The iostream library supports in-memory input/output, in which a stream is attached to a string within the program's memory. That string can be written to and read from using the iostream input and output operators. The library defines three kinds of string streams:

iostream 标准库支持内存中的输入/输出,只要将流与存储在程序内存中的 string 对象捆绑起来即可。此时,可使用 iostream 输入和输出操作符读写这个 string 对象。标准库定义了三种类型的字符串流:

  • istringstream, derived from istream, reads from a string.

    istringstream,由 istream 派生而来,提供读 string 的功能。

  • ostringstream, derived from ostream, writes to a string.

    ostringstream,由 ostream 派生而来,提供写 string 的功能。

  • stringstream, derived from iostream, reads and writes a string.

    stringstream,由 iostream 派生而来,提供读写 string 的功能。

To use any of these classes, we must include the sstream header.

要使用上述类,必须包含 sstream 头文件。

Like the fstream types, these types are derived from the iostream types, meaning that all the operations on iostreams also apply to the types in sstream. In addition to the operations that the sstream types inherit, these types have a constructor that takes a string. The constructor copies the string argument into the stringstream object. The operations that read and write the stringstream read or write the string in the object. These classes also define a member named str to fetch or set the string value that the stringstream manipulates.

fstream 类型一样,上述类型由 iostream 类型派生而来,这意味着 iostream 上所有的操作适用于 sstream 中的类型。sstream 类型除了继承的操作外,还各自定义了一个有 string 形参的构造函数,这个构造函数将 string 类型的实参复制给 stringstream 对象。对 stringstream 的读写操作实际上读写的就是该对象中的 string 对象。这些类还定义了名为 str 的成员,用来读取或设置 stringstream 对象所操纵的 string 值。

Note that although fstream and sstream share a common base class, they have no other interrelationship. In particular, we cannot use open and close on a stringstream, nor can we use str on an fstream.

注意到尽管 fstreamsstream 共享相同的基类,但它们没有其他相互关系。特别是,stringstream 对象不使用 openclose 函数,而 fstream 对象则不允许使用 str

Table 8.5. stringstream-Specific Operations
表 8.5. stringstream 特定的操作

stringstream strm;

Creates an unbound stringstream.

创建自由的 stringstream 对象

stringstream strm(s);

Creates a stringstream that holds a copy of the string s.

创建存储 s 的副本的 stringstream 对象,其中 s 是 string 类型的对象

strm.str()

Returns a copy of the string that strm holds.

返回 strm 中存储的 string 类型对象

strm.str(s)

Copies the string s into strm. Returns void.

string 类型的 s 复制给 strm,返回 void


Using a stringstream

stringstream 对象的和使用

We've seen programs that need to deal with their input a word at a time or a line at a time. The first sort of programs use the string input operator and the second use the getline function. However, some programs need to do both: They have some processing to do on a per-line basis and other work that needs to be done on each word within each line. Using stringstreamslets us do so:

前面已经见过以每次一个单词或每次一行的方式处理输入的程序。第一种程序用 string 输入操作符,而第二种则使用 getline 函数。然而,有些程序需要同时使用这两种方式:有些处理基于每行实现,而其他处理则要操纵每行中每个单词。可用 stringstreams 对象实现:

    string line, word;      // will hold a line and word from input, respectively
    while (getline(cin, line))   {            // read a line from the input into line
       // do per-line processing
       istringstream stream(line);            // bind to stream to the line we read
       while (stream >> word){          // read a word from line
           // do per-word processing
       }
    }

Here we use getline to get an entire line from the input. To get the words in each line, we bind an istringstream to the line that we read. We can then use the normal string input operator to read the words from each line.

这里,使用 getline 函数从输入读取整行内容。然后为了获得每行中的单词,将一个 istringstream 对象与所读取的行绑定起来,这样只需要使用普通的 string 输入操作符即可读出每行中的单词。

stringstreams Provide Conversions and/or Formatting

stringstream 提供的转换和/或格式化

One common use of stringstreams is when we want to obtain automatic formatting across multiple data types. For example, we might have a collection of numeric values but want their string representation or vice versa. The sstream input and output operations automatically convert an arithmetic type into its corresponding string representation or back again:

stringstream 对象的一个常见用法是,需要在多种数据类型之间实现自动格式化时使用该类类型。例如,有一个数值型数据集合,要获取它们的 string 表示形式,或反之。sstream 输入和输出操作可自动地把算术类型转化为相应的 string 表示形式,反过来也可以。

    int val1 = 512, val2 = 1024;
    ostringstream format_message;
    // ok: converts values to a string representation
    format_message << "val1: " << val1 << "\n"
                   << "val2: " << val2 << "\n";

Here we create an empty ostringstream object named format_message and insert the indicated text into that object. What's important is that the int values are automatically converted to their printable string equivalents. The contents of format_message are the characters

这里创建了一个名为 format_messageostringstream 类型空对象,并将指定的内容插入该对象。重点在于 int 型值自动转换为等价的可打印的字符串。format_message 的内容是以下字符:

val1: 512\nval2: 1024

We could retrieve the numeric value by using an istringstream to read from the string. Reading an istringstream automatically converts from the character representation of a numeric value to its corresponding arithmetic value:

相反,用 istringstreamstring 对象,即可重新将数值型数据找回来。读取 istringstream 对象自动地将数值型数据的字符表示方式转换为相应的算术值。

   // str member obtains the string associated with a stringstream
   istringstream input_istring(format_message.str());
   string dump; // place to dump the labels from the formatted message
   // extracts the stored ascii values, converting back to arithmetic types
   input_istring >> dump >> val1 >> dump >> val2;
   cout << val1 << " " << val2 << endl;  // prints 512 1024

Here we use the str member to obtain a copy of the string associated with the ostringstream we previously created. We bind input_istring to that string. When we read input_istring, the values are converted back to their original numeric representations.

这里使用 。str 成员获取与之前创建的 ostringstream 对象关联的 string 副本。再将 input_istringstring 绑定起来。在读 input_istring 时,相应的值恢复为它们原来的数值型表示形式

To read input_string, we must parse the string into its component parts. We want the numeric values; to get them we must read (and ignore) the labels that are interspersed with the data we want.

为了读取 input_string,必须把该 string 对象分解为若干个部分。我们要的是数值型数据;为了得到它们,必须读取(和忽略)处于所需数据周围的标号。



Because the input operator reads typed values, it is essential that the types of the objects into which we read be compatible with the types of the values read from the stringstream. In this case, input_istring had four components: The string value val1: followed by 512 followed by the string val2: followed by 1024. As usual, whenweread strings using the input operator, whitespace is ignored. Thus, when we read the string associated with format_message, we can ignore the newlines that are part of that value.

因为输入操作符读取的是有类型的值,因此读入的对象类型必须和由 stringstream 读入的值的类型一致。在本例中,input_istring 分成四个部分:string 类型的值 val1,接着是 512,然后是 string 类型的值 val2,最后是 1024。一般情况下,使用输入操作符读 string 时,空白符将会忽略。于是,在读与 format_message 关联的 string 时,忽略其中的换行符。

Exercises Section 8.5

Exercise 8.15:

Use the function you wrote for the first exercise in Section 8.2 (p. 291) to print the contents of an istringstream object.

使用第 8.2 节第一个习题编写的函数输出 istringstream 对象的内容。

Exercise 8.16:

Write a program to store each line from a file in a vector<string>. Now use an istringstream to read each line from the vector a word at a time.

编写程序将文件中的每一行存储在 vector<string> 容器对象中,然后使用 istringstreamvector 里以每次读一个单词的形式读取存储的行。


Team LiB
Previous Section Next Section