Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从stringstream中删除char并附加一些数据_C++_Stringstream - Fatal编程技术网

C++ 从stringstream中删除char并附加一些数据

C++ 从stringstream中删除char并附加一些数据,c++,stringstream,C++,Stringstream,在我的代码中,有一个循环将类似“数字”的内容添加到stringstream中。当循环结束时,如果要重复循环,我需要提取“,”add“}”并添加“{” 我想我可以使用ignore()删除“”,但它不起作用。你知道我该怎么做吗 例如: douCoh << '{'; for(unsigned int i=0;i<dataSize;i++) if(v[i].test) douCoh << i+1 << ','; douCoh.get(); douCoh &l

在我的代码中,有一个循环将类似“数字”的内容添加到stringstream中。当循环结束时,如果要重复循环,我需要提取“,”add“}”并添加“{”

我想我可以使用ignore()删除“”,但它不起作用。你知道我该怎么做吗

例如:

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

doucho您可以使用直接从基础字符串中删除最后一个字符。

您可以提取字符串(与成员一起),使用删除最后一个字符,然后将新字符串作为缓冲区重置为

但是,更好的解决方案是不首先插入多余的
,“
,方法如下:

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 << '}';
std::ostringstream Doucho;
常量字符*分隔符=”;

为什么不直接检查计数器?而不插入“,”

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

doucho享受std::copy、迭代器和traits带来的乐趣。
您必须假设您的数据是反向可写的(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';
}
#包括
#包括
#包括
名称空间我的
{
模板
无效打印(std::ostream&out、迭代器开始、迭代器结束)
{
out(out,“,”);
}
out
stringstream-doucho;

对于(unsigned int i=0;i自c++11以来,我使用
pop_back()
string的方法找到了这种方法。可能不如上面更聪明的方法好,但在更复杂的情况下和/或对懒惰的人有用

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

doucho您可以使用
stringstream::seekp
查找
stringstream
并返回1个字符。请注意,它不会删除最后一个字符,而只移动写入头。在这种情况下,这就足够了,因为我们使用
}
覆盖最后一个字符

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

doucho我遇到了这个问题,我发现您可以简单地执行以下操作:

douCoh.seekp(-1, std::ios_base::end);
和保持插入数据。正如其他人所说,避免首先插入坏数据可能是理想的解决方案,但在我的情况下,这是第三方库函数的结果,而且我希望避免将数据复制到字符串。

\35; include
#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;   
}
#包括 #包括 #包括 模板 std::string内爆(std::vector vec,std::string&&delim) { std::stringstream-ss; std::copy(vec.begin()、vec.end()、std::ostream_迭代器(ss、delim.c_str()); 如果(!vec.empty()){ seekp(-1*delim.size(),std::ios\u base::end);
请添加一些示例来说明您的观点。我如何获取基础字符串?str()返回字符串的副本而不是引用,不是吗?是的,您使用str()获取内容的副本。std::ostringstream::str
函数的另一个重写允许更改缓冲区。但是,此解决方案需要两份缓冲区内容副本,可以是coslty。我认为不可能检查计数器,因为可能有一些对象未通过测试。需要另一个计数器(可以是bool),或我更改分隔符变量的技巧可以使用。不可能预测v[j]的值.test for j>i,然后再进行编码。否则,您必须编写完整的循环,而不是依赖std::copy。欢迎使用StackOverflow!如果您为那些不理解的人解释代码,这将非常有用。请记住,它不会从缓冲区中删除数据,因此您需要覆盖该数据。“更好”取决于上下文,并包括主观考虑。避免在序列末尾使用一个多余的逗号通常需要向循环添加额外的状态和额外的比较,从而导致在多次迭代中执行较慢。在许多情况下,只需在lo之后删除/替换一个多余的尾随字符op Finished会产生更干净、更小、更快的代码。我不明白为什么这个相当笨拙的解决方案会被接受,特别是当最终“更好”的问题被回避时。你真的测试过这个吗?因为这不起作用:内爆(/*…*/)!=“1,2,3”。
#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;   
}