【问题标题】:concatenate stringstream in c++在 C++ 中连接字符串流
【发布时间】:2012-01-04 03:05:12
【问题描述】:

如何连接两个字符串流?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include "types.h"    

int main () {
    char dest[1020] = "you";
    char source[7] = "baby";
    stringstream a,b;
    a << source;
    b << dest;
    a << b; /*HERE NEED CONCATENATE*/
    cout << a << endl;
    cout << a.str() << endl;
    return 0;
}

两次尝试的输出如下:

0xbf8cfd20
baby0xbf8cfddc

所需的输出是babyyou

【问题讨论】:

    标签: c++ concatenation stringstream


    【解决方案1】:

    应该是:

    b << dest;
    a << b.str();
    

    stringstream::str 返回stringstream 中的底层字符串。

    【讨论】:

    • 当然,如前所述,在这种情况下您不需要 2 个stringstreams,但是我假设给定的示例是一些更复杂用例的简单版本。
    • 这将创建 b 的字符串数据的副本;我认为提问者可能正在寻找一种方法来避免这样做。
    【解决方案2】:

    或者

    a << b.rdbuf();
    

    假设 get 指针位于流的开头,以避免为内容分配另一个 std::string

    【讨论】:

      【解决方案3】:

      更一般地跨 iostream:

      std::istream is1, is2; // eg. (i)stringstream
      std::ostream os;       // eg. (o)stringstream
      
      os << is1.rdbuf();
      os << is2.rdbuf();
      os << std::flush;
      

      这适用于文件流、std::cin 等以及字符串流

      【讨论】:

        【解决方案4】:

        您不需要std::stringstream 的两个实例。一个就足够了。

        std::stringstream a;
        a << source << dest;
        
        std::string s = a.str(); //get the underlying string
        

        【讨论】:

          【解决方案5】:

          问题是“如何连接流”,答案解释了如何连接流的内容。这是一个可用于将两个 istream 连接成一个 istream 的类(文件 ConcatStreams.h):

          class ConcatStreams
          : public std::streambuf {
          std::streambuf* sbuf1_;
          std::streambuf* sbuf2_;
          char*           buffer_;
          int useBuf;
          int bufSize;
          public:
          ConcatStreams(std::streambuf* sbuf1, std::streambuf* sbuf2)
              : bufSize(1024), sbuf1_(sbuf1), sbuf2_(sbuf2), buffer_(new char[bufSize]), useBuf(1) {
          }
          ConcatStreams(const ConcatStreams& orig);
          virtual ~ConcatStreams() { delete[] this->buffer_; }
          int underflow() {
              if (this->gptr() == this->egptr()) {
                  // get data into buffer_, obtaining its input from
                  // this->sbuf_; if necessary resize buffer
                  // if no more characters are available, size == 0.
                  std::streamsize size=0;
                  if(useBuf==1) {
                      size = this->sbuf1_->sgetn(this->buffer_, bufSize);
                      if(!size) { useBuf++;}
                  } 
                  if(useBuf==2) {
                      size = this->sbuf2_->sgetn(this->buffer_, bufSize);
                      if(!size) { useBuf++;}
                  }
                  this->setg(this->buffer_, this->buffer_, this->buffer_ + size);
              }
              return this->gptr() == this->egptr()
                   ? std::char_traits<char>::eof()
                   : std::char_traits<char>::to_int_type(*this->gptr());
           }
          };
          

          使用它:

          #include "ConcatStreams.h"
          istringstream msgIn1("this is a stream.");
          istringstream msgIn2("this is another stream.");
          ConcatStreams cs(msgIn1.rdbuf(), msgIn2.rdbuf());
          istream msgIn(&cs);
          cout << "'" << msgIn.rdbuf() << "'" << endl;
          

          基本上,该类使用传递给它的流中的流缓冲区来创建一个新的流缓冲区,该流缓冲区首先读取第一个流缓冲区,然后在完成第一个流缓冲区后读取第二个流缓冲区。

          【讨论】:

          • 这个类有问题(bufSize 的初始化在构造buffer_ 的使用之后进行)并且通常是不必要的低级。这是一个c++17版本stackoverflow.com/a/49441066/85371
          【解决方案6】:

          只需将a &lt;&lt; b 替换为a &lt;&lt; b.str()

          【讨论】:

            猜你喜欢
            • 2012-09-05
            • 1970-01-01
            • 1970-01-01
            • 2010-12-16
            • 2017-06-24
            • 1970-01-01
            • 2013-08-20
            相关资源
            最近更新 更多