逐行反转字符串流

时间:2013-09-21 20:52:34

标签: c++ ostringstream

ostringstream ss;
ss << "(1,2)\n" << "(1,3)\n" << "(1,4)\n" ;
cout << ss.str();

应打印以下内容:

  

(1,2)

     

(1,3)

     

(1,4)

如何按行反转输出以便打印:

  

(1,4)

     

(1,3)

     

(1,2)

4 个答案:

答案 0 :(得分:3)

您可以使用自定义std::streambuf在内部保留一堆std::string s并使用str()成员将它们组合在一起。例如:

#include <iostream>
#include <numeric>
#include <streambuf>
#include <string>
#include <vector>

class stackbuf
    : public std::streambuf
{
    std::vector<std::string> d_lines;
    int overflow(int c) {
        if (c != std::char_traits<char>::eof()) {
            this->d_lines.back().push_back(c);
            if (c == '\n') {
                this->d_lines.push_back(std::string());
            }
        }
        return std::char_traits<char>::not_eof(c);
    }
public:
    stackbuf(): d_lines(1) {}
    std::string str() const {
        return std::accumulate(this->d_lines.rbegin(),
                               this->d_lines.rend(),
                               std::string());
    }
};

int main()
{
    stackbuf sbuf;
    std::ostream out(&sbuf);
    out << "(1, 2)\n(1, 3)\n(1, 4)\n";
    std::cout << sbuf.str();
}

对于实际应用程序,显然,您应该在流缓冲区中设置一个缓冲区以提高性能。您可能还想创建一个直接初始化流的流缓冲区的自定义流。

答案 1 :(得分:1)

您可以使用反向迭代器:

std::ostringstream ss{ "(1,2)\n(1,3)\n(1,4)\n" };
std::string str = ss.str();

std::copy( str.rbegin(), str.rend(),
           std::ostream_iterator<std::string>{std::cout, "\n"} );

此代码需要:

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

和基本的C ++ 11支持。

答案 2 :(得分:1)

使用原始代码与C ++ 98

  ostringstream ss;
  ss << "(1,2)\n" << "(1,3)\n" << "(1,4)\n" ;
  cout << ss.str();

  //assign a string to the contents of the ostringstream:
  string rawlines = ss.str();

  //now create an input stringstream with the value of the rawlines
  istringstream iss(rawlines);

  string temp;//just a temporary object used for storage
  vector<string> lines;//this is where your lines will be held

  //now iterate over the stream and store the contents into the vector `lines`:
  while(getline(iss, temp)) {
      lines.push_back(temp);
  }

  //now reverse the contents:
  reverse(lines.begin(), lines.end());

  //see what's inside:
  for (vector<string>::const_iterator it = lines.begin(); it != lines.end(); ++it) {
    cout << *it << endl;
  }

这将打印:

(1,4)
(1,3) 
(1,2)

根据需要

注意:这会删除原始字符串中的换行符。 而且,这需要:

//for `getline`:
#include <cstdlib>
//for `reverse`:
#include <algorithm>
//for `string`:
#include <string>
//for `vector`:
#include <vector>

答案 3 :(得分:1)

这将是最经典的方式,最好地利用标准C ++库。

#include <iostream>                                                      
#include <sstream>
#include <stack>
#include <string>

using namespace std;

int main(int argv, char* arv[])
{
  ostringstream oss;
  oss << "(1,2)\n" << "(1,3)\n" << "(1,4)\n" ;
  cout << oss.str() << "----------\n";
  // Reverse lines
  // Fill an istringstream with buffer contents of the ostringstream
  istringstream iss(oss.str());
  stack<string> stk;
  while (iss) {
    string s;
    if (!getline(iss, s)) break; // Read a line
    s += '\n';                   // Put back newline stripped by readline
    stk.push(s);                 // Push line to stack
  }
  oss.clear();                   // Clear state of the ostringstream
  oss.str("");                   // Clear contents of the ostringstream for reuse
  while (!stk.empty()) {
    string s;
    s = stk.top();               // Get top of stack
    oss << s;                    // Output it to the ostringstream
    stk.pop();                   // Pop and throw away top of stack
  }
  cout << oss.str();
  return 0;
}