C++ 从字符串流中删除字符并附加一些数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4546021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:42:14  来源:igfitidea点击:

remove char from stringstream and append some data

c++stringstream

提问by lord.didger

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.

在我的代码中,有一个循环将诸如“数字”之类的东西添加到 stringstream。当它结束时,如果要重复循环,我需要提取 ',' 添加 '}' 并添加 '{'。

I thought i can use ignore() to remove ',' but it didn't work. Do you know how I can do what I describe?

我以为我可以使用 ignore() 来删除 ',' 但它没有用。你知道我怎样才能做到我所描述的吗?

example:

例子:

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

回答by bcmpinc

You can seek the stringstreamand 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 }.

您可以使用 查找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 << '}';

回答by Sylvain Defresne

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

您可以提取字符串(使用str()成员),删除最后一个字符,std::string::erase然后将新字符串作为缓冲区重置为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 << '}';

回答by jdehesa

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.

并不断插入数据。正如其他人所说,首先避免插入错误数据可能是理想的解决方案,但在我的情况下是第 3 方库函数的结果,而且我想避免将数据复制到字符串。

回答by Drum Inc

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

回答by DarioP

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.

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 << '}';

回答by Beno?t

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.

享受 std::copy、迭代器和特征带来的乐趣。您要么必须假设您的数据是可反向迭代的(end - 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';
}

回答by Daniel Hornik

#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<<'
douCoh << '{';
for(unsigned int i=0;i<dataSize;i++){
  if(v[i].test){
    douCoh << i+1;
    if(i != dataSize - 1) douCoh << ',';
  }
}
/*douCoh.get();*/ douCoh << '}';
'; } return ss.str(); } int main() { std::cout<<implode(std::vector<std::string>{"1", "2", "3"}, ", "); return 0; }

回答by Bj?rn Pollex

You could use std::string::eraseto remove the last character directly from the underlying string.

您可以使用std::string::erase直接从底层字符串中删除最后一个字符。

回答by RedX

Why not just check the counter? And not insert the ','

为什么不直接查柜台呢?而不是插入','

##代码##