【问题标题】:std::ostringstream overwriting initializing stringstd::ostringstream 覆盖初始化字符串
【发布时间】:2025-11-30 13:35:01
【问题描述】:

以下代码在clang++-7 上产生“0004567”

#include <iostream>
#include <sstream>

using namespace std;

int main() {
    ostringstream oss{"1234567"};
    oss << "000";
    cout << oss.str() << endl;
}

现在这是正确的 STL 实现吗?

我想不出用将被覆盖的字符串进行初始化有什么用...

【问题讨论】:

  • 它就像用std::ofstream打开一个非空文件一样有用。试试ostringstream oss{"1234567", std::ios_base::app};。或std::ios_base::ate
  • 字符串流的重点在于它们不是文件。尽管有可用性,但模拟文件行为毫无意义。 ::ate 是这里合理的默认值。

标签: c++ string c++11 stl c++17


【解决方案1】:

@IgorTandetnik 给了你一个解决方案 - 添加 std::ios_base::app std::ostringstream 构造函数参数。

但是,将初始字符串(并且只有一个字符串)传递给构造函数没有任何好处。该参数仍会被复制,类似于 oss &lt;&lt; "1234567"; 所做的那样,但它需要提供一个额外的构造函数参数,这可能会引入编程错误(并且在您的代码中确实如此)。

我建议保持简单:

ostringstream oss;
oss << "1234567";
oss << "000";
// alternatively, just do oss << "1234567000";

【讨论】:

  • 谢谢。现在我想知道为什么 ios_base::app 不是默认模式,因为当前模式不可用。在对标准进行了如此多的更新之后,STL 仍然令人沮丧地不友好......
  • @gatopeich IOStreams 经常因其糟糕的设计而受到批评。没错,IMO。
  • 确实,@Maxim。看起来 IOStreams 的主要设计目标是“看起来与任何其他语言特别是 C 非常不同”。剩下的就是细节?