内联替换 std::stringstream 中的字符

replacing chars in std::stringstream inline

我想知道是否可以使用 std::replace 将字符串流中的双引号替换为单引号。

我有:

std::replace(
    std::ostreambuf_iterator<char>(ssScript),
    std::ostreambuf_iterator<char>(),
    '"', '\''
);

当然 ostreambuf_iterator 没有默认构造函数,因此无法编译。

是否有另一种方法来替换像这样的内联字符串流中出现的字符?

std::stringstream class 提供了一个用于操作流的接口,而不是它的内容。要操作流的内容,您必须获取字符串,对其进行操作,然后将字符串放入流中,如下所示:

#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>

int main(void)
{
    std::stringstream ss;
    ss << "\"this is a string in a stream\"";
    std::cout << "Before: " << ss.str() << std::endl;
    std::string s = ss.str();
    std::replace(s.begin(), s.end(), '"', '\'');
    ss.str(s);
    std::cout << "After: " << ss.str() << std::endl;
    return 0;
}

你得到:

Before: "this is a string in a stream"
After: 'this is a string in a stream'

假设字符串的生成器在生成字符串时仅使用 stringstreamostream 接口,则有可能(一旦你破译了文档,实际上很容易)构建一个自定义的 ostream,它既可以过滤又可以附加到您可以完全访问的字符串。

示例:

#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <iostream>
#include <string>

namespace io = boost::iostreams;

// a custom filter
struct replace_chars
{
    typedef char                   char_type;
    typedef io::output_filter_tag  category;


    replace_chars(char_type from, char_type to) : from(from), to(to) {}

    template<typename Sink>
    bool put(Sink& snk, char_type c)
    {
        if (c == from) c = to;
        return io::put(snk, c);
    }

    char_type from, to;
};

// some code that writes to an ostream    
void produce_strings(std::ostream& os)
{
    os << "The quick brown fox called \"Kevin\" jumps over the lazy dog called \"Bob\"" << std::endl;
    os << "leave 'these' as they are" << std::endl;
    os << "\"this\" will need to be flushed as there is no endl";
}

// test
int main()
{
    // a free buffer to which I have access
    std::string buffer;

    // build my custom ostream    
    io::filtering_ostream stream;
    stream.push(replace_chars('"', '\''));   // stage 1 - filter
    stream.push(io::back_inserter(buffer));  // terminal stage - append to string

    // pass the ostream interface of my filtering, string-producing stream    
    produce_strings(stream);
    // flush in case the callee didn't terminal with std::endl
    stream.flush();

    std::cout <<buffer <<std::endl;
}

预期输出:

The quick brown fox called 'Kevin' jumps over the lazy dog called 'Bob'
leave 'these' as they are
'this' will need to be flushed as there is no endl