可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
I thought i can use ignore() to remove ',' but it didn't work. Do you know how I can do what I describe?
example:
douCoh << '{';
for(unsigned int i=0;i<dataSize;i++)
if(v[i].test) douCoh << i+1 << ',';
douCoh.get(); douCoh << '}';
回答1:
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 << '}';
回答2:
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 << '}';
回答3:
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.
回答4:
stringstream douCoh;
for(unsigned int i=0;i<dataSize;i++)
if(v[i].test)
douCoh << ( douCoh.tellp()==0 ? '{' : ',' ) << i+1;
douCoh << '}';
回答5:
I've found this way using pop_back()
string's method since c++11. Probably not so good as smarter ones above, but useful in much more complicated cases and/or for lazy people.
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:
You could use std::string::erase
to remove the last character directly from the underlying string.
回答7:
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';
}
回答8:
Why not just check the counter? And not insert the ','
douCoh << '{';
for(unsigned int i=0;i<dataSize;i++){
if(v[i].test){
douCoh << i+1;
if(i != dataSize - 1) douCoh << ',';
}
}
/*douCoh.get();*/ douCoh << '}';