2

我想使用std::copy并将std::ostream_iteratora 中的字符串打印vector为括号之间的逗号分隔列表。所以我必须处理删除", "最后一个元素之后的问题。

我试过这个

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

int main() {

    std::vector<std::string> v;
    v.push_back("a");
    v.push_back("b");
    v.push_back("c");

    std::stringstream os;
    os << '(';
    std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(os, ", "));
    os.seekp(-2, std::ios_base::cur);
    os << ')';

    std::cout << os.str() << ".";

    return 0;
}

输出:

(a, b, c) .
         ^

但是我得到的输出在右括号之后有一个额外的空格字符,因为seekp只是移动了书写位置但没有删除书写的字符。

有没有办法删除最后一个字符或写一个EOF?

4

2 回答 2

8

一开始就不写多余的东西怎么样", "...

if(!v.empty())
{
   std::copy(v.begin(), v.end()-1, std::ostream_iterator<std::string>(os, ", "));
   os << v.back();
}
于 2013-11-06T16:18:00.587 回答
2

您不仅在使用 时删除字符seekp,还在设置当前光标。您的下一条语句将覆盖该字符,但缓冲区中仍有后续字符。有几种方法可以解决这个问题:

不要输出完整的模式:

std::ostringstream os;
os << '(';
std::copy(v.begin(), v.end() - 1, std::ostream_iterator<std::string>(os, ", "));
if (v.size() > 1) // or (!v.empty())
    os << *(v.end() - 1) << ')';

这将使用模式打印除向量的最后一个字符之外的所有字符(将完全避免额外的“,”组合)。

或者,您可以手动重置缓冲区:

std::ostringstream os;
os << '(';
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(os, ", "));
std::string t = os.str();
t.resize(t.size() - 2);
os.str() = t;
os << ')';

或者,也许是更统一的解决方案(如果您不反对不使用副本):

std::ostringstream os;
os << '(';
if (v.size() > 1) // or (!v.empty())
    os << v.front();

std::for_each(v.begin() + 1, v.end(), [&](const std::string& s)
{
    os << ", " << s;
});
os << ")";
于 2013-11-06T16:21:57.607 回答