Удалите char из stringstream и добавьте некоторые данные
В моем коде есть цикл, который добавляет sth как этот "число" в stringstream. Когда это закончится, мне нужно извлечь ',' add '}' и добавить '{', если цикл повторяется.
Я думал, что могу использовать ignore() для удаления ',', но это не сработало. Знаете ли вы, как я могу делать то, что я описываю?
Пример:
douCoh << '{';
for(unsigned int i=0;i<dataSize;i++)
if(v[i].test) douCoh << i+1 << ',';
douCoh.get(); douCoh << '}';
Ответы
Ответ 1
Вы можете извлечь строку (с элементом str()
), удалить последний char с помощью std::string::erase
, а затем reset новую строку в качестве буфера в 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 << '}';
Ответ 2
Вы можете найти 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 << '}';
Ответ 3
У меня была эта проблема, и я узнал, что вы можете просто сделать:
douCoh.seekp(-1, std::ios_base::end);
И продолжайте вставлять данные. Как утверждали другие, избегать вставки плохих данных в первую очередь, вероятно, является идеальным решением, но в моем случае это было результатом функции сторонней библиотеки, а также я хотел избежать копирования данных в строки.
Ответ 4
stringstream douCoh;
for(unsigned int i=0;i<dataSize;i++)
if(v[i].test)
douCoh << ( douCoh.tellp()==0 ? '{' : ',' ) << i+1;
douCoh << '}';
Ответ 5
Я нашел этот способ, используя метод pop_back()
string с С++ 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 << '}';
Ответ 6
Получайте удовольствие от std:: copy, iterators и traits.
Вы либо должны предположить, что ваши данные обращаются по итерации (конец - 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';
}
Ответ 7
Вы можете использовать std::string::erase
, чтобы удалить последний символ непосредственно из базовой строки.
Ответ 8
Почему бы просто не проверить счетчик? И не вставляйте ','
douCoh << '{';
for(unsigned int i=0;i<dataSize;i++){
if(v[i].test){
douCoh << i+1;
if(i != dataSize - 1) douCoh << ',';
}
}
/*douCoh.get();*/ douCoh << '}';
Ответ 9
#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;
}