在std::stringstream中替换字符

6

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

目前的代码如下:

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

当然,ostreambuf_iterator没有默认构造函数,所以这段代码无法编译。

是否有其他方法可以像这样内联地替换stringstream中的字符出现次数?

2个回答

7

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

#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;
}

你将得到:

之前:"this is a string in a stream"
之后:'this is a string in a stream'


我本来希望避免字符串复制,因为它有点低效,但我理解你的意思。我本来希望有一种内联解决方案,但如果不可能,那就算了。 - stack user
在许多方面,std::stringstream都需要更好功能的替代品。也许boost库有你需要的东西? - Richard Hodges

3
假设字符串的生产者只在生成字符串时使用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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接