c++ - std::stringstream 可以设置失败/坏位的方法?

标签 c++ stringstream getline

我用于简单字符串拆分的一段常见代码如下所示:

inline std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

有人提到这会默默地“吞下”std::getline 中发生的错误。当然,我同意是这样的。但我突然想到,在实践中这里可能会出现什么问题,我需要担心。基本上这一切都归结为:

inline std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }

    if(/* what error can I catch here? */) {
        // *** How did we get here!? ***
    }

    return elems;
}

stringstreamstring 支持,因此我们不必担心与从文件读取相关的任何问题。这里没有进行类型转换,因为 getline 只是读取直到它看到行分隔符或 EOF。所以我们不会得到像 boost::lexical_cast 这样的东西必须担心的任何错误。

除了未能分配足够的内存可能会出错,我实在想不出还有什么,但这只会在 std::getline 之前抛出一个 std::bad_alloc 甚至发生。我错过了什么?

最佳答案

我无法想象这个人认为可能会出现什么错误,你应该请他们解释。除了您提到的分配错误外,没有什么会出错,分配错误是抛出而不是吞噬。

我看到您直接遗漏的唯一一件事是 ss.fail() 在 while 循环之后保证为真,因为这是被测试的条件。 (bool(stream) 等同于 !stream.fail()不是 stream.good()。 ) 正如预期的那样,ss.eof() 也将为真,表明失败是由于 EOF。

但是,对于实际发生的事情可能会有一些混淆。因为 getline 使用 delim-terminated 字段而不是 delim-separated 字段,输入"a\nb\n" 等数据有两个字段而不是三个字段,这可能会令人惊讶。对于行,这是完全有意义的(并且是 POSIX 标准),但是您希望在 中找到多少字段,delim'-' a-b-” split 后?


顺便说一句,我是这样的write split :

template<class OutIter>
OutIter split(std::string const& s, char delim, OutIter dest) {
  std::string::size_type begin = 0, end;
  while ((end = s.find(delim, begin)) != s.npos) {
    *dest++ = s.substr(begin, end - begin);
    begin = end + 1;
  }
  *dest++ = s.substr(begin);
  return dest;
}

这首先避免了 iostream 的所有问题,避免了额外的拷贝(stringstream 的支持字符串;加上 substr 返回的 temp,如果支持的话,甚至可以使用 C++0x 右值引用来移动语义,如所写) ,具有我期望的 split 行为(与您的行为不同),并且适用于任何容器。

deque<string> c;
split("a-b-", '-', back_inserter(c));
// c == {"a", "b", ""}

关于c++ - std::stringstream 可以设置失败/坏位的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2562906/

相关文章:

c++ - 对和字符串流

c++ - 访问 ".txt"文件中的信息并转到确定的行

c++ - "C++ Concurrency in Action"中的阿姆达尔定律

c++ - 为什么tellp() 是一个非常量?

c++ - 有没有办法从 string_view 创建字符串流而不复制数据?

c++ - 为什么 cin 在使用 getline 后没有获取缓冲区数据?

c++ - getline(cin, var) 不工作!

c++ - 为什么 clang-tidy 建议在任何地方添加 [[nodiscard]] ?

c++ - 如何使用 Qtcreator 在 C++ 中拆分字符串

c++ - 从类中返回指向 unique_ptr 的裸指针是否完全可以