字符串流的不同插入位置

different insert position with stringstream

本文关键字:插入位置 字符串      更新时间:2023-10-16

我很难从下面的代码中理解字符串流的不同行为。有人可以阐明流的内部工作原理吗?

int main(){
    string str = "123";  
    stringstream ss(str);
    cout << ss.str() <<endl;  
    ss << str;
    cout << ss.str() <<endl;
} 

输出:

123

123

int main(){
    string str = "123";  
    stringstream ss;
    ss << str;
    cout << ss.str() <<endl;  
    ss << str;
    cout << ss.str() <<endl;
} 

输出:

123

123123

这是因为实际的写入位置没有更新,所以当你在第一个示例中

ss << str;

覆盖当前字符串。

使用字符串流构造函数std::ios_base::ate

标志
std::stringstream ss(str,
    std::ios_base::in | std::ios_base::out | std::ios_base::ate);

将读/写指针定位在末尾。

请参阅此参考中的示例。

所有流都是这样,当您打开文件流时,位置也在开头。

std::stringstream对象在内部记住上次写入结束的位置。当您使用运算符时<<这会更新,但当您使用某些字符串构造此流时,不会更新:

stringstream ss(str);
cout << ss.tellp() <<endl;  
ss << str;
cout << ss.tellp() <<endl;

输出:

0
3

即在执行第一个ss << str;时,它只是使用"123"重写"123",这已经存在。您可以使用setp设置要插入下一个字符的位置

stringstream ss(str);
cout << ss.str() <<endl;  
ss.seekp(3);                 // <-- sets outPUT position
ss << str;
cout << ss.str() <<endl;

或者,您可以设置模式,这将确保在使用std::stringstream::app的每个写入操作之前将此位置设置为末尾,或者您可以使用 std::ios_base::ate ,它会在打开后立即寻求流的末尾:

stringstream ss(str, std::stringstream::out | std::stringstream::app);

构造std::stringstream会将位置设置为流的开头。位置在写入流或调用适当的查找方法后更新。