remove char from stringstream and append some data

后端 未结 9 1444
情深已故
情深已故 2020-12-31 01:42

In my code there is a loop that adds sth like that \"number,\" to stringstream. When it ends, I need to extract \',\' add \'}\' and add \'{\' if the loop is to repeated.

相关标签:
9条回答
  • 2020-12-31 01:59

    I have had this very problem and I found out that you can simply do:

    douCoh.seekp(-1, std::ios_base::end);
    

    And the keep inserting data. As others stated, avoiding inserting the bad data in the first place is probably the ideal solution, but in my case was the result of a 3rd party library function, and also I wanted to avoid copying the data to strings.

    0 讨论(0)
  • 2020-12-31 02:00

    You can extract the string (with the str() member), remove the last char with std::string::erase and then reset the new string as buffer to the std::ostringstream.

    However, a better solution would be to not insert the superfluous ',' in the first place, by doing something like that :

    std::ostringstream douCoh;
    const char* separator = "";
    
    douCoh << '{';
    for (size_t i = 0; i < dataSize; ++ i)
    {
      if (v[i].test)
      {
        douCoh << separator << i + 1;
        separator = ",";
      }
    }
    douCoh << '}';
    
    0 讨论(0)
  • 2020-12-31 02:00
    stringstream douCoh;
    for(unsigned int i=0;i<dataSize;i++)
      if(v[i].test)
        douCoh << ( douCoh.tellp()==0 ? '{' : ',' ) << i+1;
    douCoh << '}';
    
    0 讨论(0)
  • 2020-12-31 02:04

    Have fun with std::copy, iterators and traits. You either have to assume that your data is reverse iterable (end - 1) or that your output can be rewinded. I choose it was easier to rewind.

    #include <ostream>
    #include <algorithm>
    #include <iterator>
    
    namespace My
    {
      template<typename Iterator>
      void print(std::ostream &out, Iterator begin, Iterator end)
      {
        out << '{';
        if (begin != end) {
          Iterator last = end - 1;
          if (begin != last) {
            std::copy(begin, last, std::ostream_iterator< typename std::iterator_traits<Iterator>::value_type  >(out, ", "));
          }
          out << *last;
        }
        out << '}';
      }
    }
    
    #include <iostream>
    
    int main(int argc, char** argv)
    {
      My::print(std::cout, &argv[0], &argv[argc]);
      std::cout << '\n';
    }
    
    0 讨论(0)
  • 2020-12-31 02:04
    #include <sstream>
    #include <vector>
    #include <iterator>
    #include <algorithm>
    
    template<typename T>
    std::string implode(std::vector<T> vec, std::string&& delim) 
    {
        std::stringstream ss;
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<std::string>(ss, delim.c_str()));
    
        if (!vec.empty()) {
            ss.seekp(-1*delim.size(), std::ios_base::end);
            ss<<'\0';
        }
    
        return ss.str();
    }
    
    int main()
    {
        std::cout<<implode(std::vector<std::string>{"1", "2", "3"}, ", ");
    
        return 0;   
    }
    
    0 讨论(0)
  • 2020-12-31 02:05

    You can seek the stringstream and go back 1 character, using stringstream::seekp. Note that it does not remove the last character, but only moves the write head. This is sufficient in this case, as we overwrite the last character with an }.

    douCoh << '{';
    for(unsigned int i=0;i<dataSize;i++)
      if(v[i].test) douCoh << i+1 << ',';
    douCoh.seekp(-1,douCoh.cur); douCoh << '}';
    
    0 讨论(0)
提交回复
热议问题