удалить char из stringstream и добавить некоторые данные - PullRequest
18 голосов
/ 28 декабря 2010

В моем коде есть цикл, который добавляет sth как этот "номер" в поток строк.Когда он заканчивается, мне нужно извлечь ',' добавить '}' и добавить '{', если цикл повторяется.

Я думал, что могу использовать ignore (), чтобы удалить ',' но это не такт работа.Вы знаете, как я могу сделать то, что я описываю?

пример:

douCoh << '{';
for(unsigned int i=0;i<dataSize;i++)
  if(v[i].test) douCoh << i+1 << ',';
douCoh.get(); douCoh << '}';

Ответы [ 9 ]

34 голосов
/ 28 декабря 2010

Вы можете извлечь строку (с помощью элемента str()), удалить последний символ с помощью std::string::erase и затем сбросить новую строку в качестве буфера на std::ostringstream.

Однако, лучшим решением было бы не вставлять лишнее ',' во-первых, выполнив что-то вроде этого:

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 << '}';
29 голосов
/ 21 октября 2014

Вы можете найти stringstream и вернуться назад на 1 символ, используя stringstream::seekp.Обратите внимание, что он не удаляет последний символ, а только перемещает головку записи.В этом случае этого достаточно, поскольку мы перезаписываем последний символ на }.

douCoh << '{';
for(unsigned int i=0;i<dataSize;i++)
  if(v[i].test) douCoh << i+1 << ',';
douCoh.seekp(-1,douCoh.cur); douCoh << '}';
15 голосов
/ 22 февраля 2016

У меня была именно эта проблема, и я обнаружил, что вы можете просто сделать:

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

И продолжать вставлять данные.Как говорили другие, во-первых, избегание вставки неверных данных, возможно, является идеальным решением, но в моем случае это было результатом использования сторонней библиотечной функции, а также я хотел избежать копирования данных в строки.

4 голосов
/ 08 декабря 2011
stringstream douCoh;
for(unsigned int i=0;i<dataSize;i++)
  if(v[i].test)
    douCoh << ( douCoh.tellp()==0 ? '{' : ',' ) << i+1;
douCoh << '}';
3 голосов
/ 10 апреля 2013

Я нашел этот способ, используя pop_back() метод строки начиная с c ++ 11. Вероятно, не так хорошо, как умнее выше, но полезно в гораздо более сложных случаях и / или для ленивых людей.

douCoh << '{';
for(unsigned int i=0;i<dataSize;i++)
  if(v[i].test) douCoh << i+1 << ',';

string foo(douCoh.str());
foo.pop_back();
douCoh.str(foo);
douCoh.seekp (0, douCoh.end);  

douCoh << '}';
1 голос
/ 28 декабря 2010

Веселитесь с std :: copy, итераторами и чертами.Вы должны либо предположить, что ваши данные являются итеративными в обратном направлении (конец - 1), либо что ваш вывод может быть перезаписанЯ выбираю, что было легче перематывать.

#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 голосов
/ 25 июня 2019
#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 голосов
/ 28 декабря 2010

Почему бы просто не проверить счетчик?И не вставляйте ','

douCoh << '{';
for(unsigned int i=0;i<dataSize;i++){
  if(v[i].test){
    douCoh << i+1;
    if(i != dataSize - 1) douCoh << ',';
  }
}
/*douCoh.get();*/ douCoh << '}';
0 голосов
/ 28 декабря 2010

Вы можете использовать std::string::erase, чтобы удалить последний символ непосредственно из базовой строки.

...