方法std :: stringstream可以设置失败/坏位? [英] Ways std::stringstream can set fail/bad bit?

查看:264
本文介绍了方法std :: stringstream可以设置失败/坏位?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A common piece of code I use for simple string splitting looks like this:

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 。当然,我同意这种情况。但是在我看来,在这里在实践中可能会出错,我需要担心。基本上可以归结为:

Someone mentioned that this will silently "swallow" errors occurring in std::getline. And of course I agree that's the case. But it occurred to me, what could possibly go wrong here in practice that I would need to worry about. basically it all boils down to this:

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

A stringstream 字符串支持,因此我们不必担心从文件读取相关的任何问题。这里没有类型转换,因为 getline 只是直到看到行分隔符或 EOF 。因此,我们不能得到任何像 boost :: lexical_cast 不得不担心的错误。

A stringstream is backed by a string, so we don't have to worry about any of the issues associated with reading from a file. There is no type conversion going on here since getline simply reads until it sees the line delimeter or EOF. So we can't get any of the errors that something like boost::lexical_cast has to worry about.

我根本不能想到的东西,除了没有分配足够的内存可能会出错,但是只会在<$ c $之前抛出一个 std :: bad_alloc c> std :: getline 甚至发生。

I simply can't think of something besides failing to allocate enough memory that could go wrong, but that'll just throw a std::bad_alloc well before the std::getline even takes place. What am I missing?

推荐答案

我不能想象这个人认为可能发生的错误,你应该要求他们解释。除了分配错误,除非分配错误被丢弃,否则不会出错。

I can't imagine what errors this person thinks might happen, and you should ask them to explain. Nothing can go wrong except allocation errors, as you mentioned, which are thrown and not swallowed.

我看到的直接丢失的唯一的东西是 ss.fail()在while循环后保证为true,因为这是被测试的条件。 ( bool(stream)等效于!stream.fail() code> stream.good()。)如预期, ss.eof()也将为true,到EOF。

The only thing I see that you're directly missing is that ss.fail() is guaranteed to be true after the while loop, because that's the condition being tested. (bool(stream) is equivalent to !stream.fail(), not stream.good().) As expected, ss.eof() will also be true, indicating the failure was due to EOF.

但是,对于实际发生的事情可能有些混乱。由于 getline 使用分隔 - 终止字段,而不是分隔数据如a \\\
b\\\
有两个而不是三个字段,这可能是令人惊讶的。对于行,这是完全有意义的(并且是POSIX标准),但有多少字段, delim ' - 'ab - 后找到

However, there might be some confusion over what is actually happening. Because getline uses delim-terminated fields rather than delim-separated fields, input data such as "a\nb\n" has two instead of three fields, and this might be surprising. For lines this makes complete sense (and is POSIX standard), but how many fields, with a delim of '-', would you expect to find in "a-b-" after splitting?

这里是我 分割

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

这避免了iostreams的所有问题, (stringstream的支持字符串;加上substr返回的temp甚至可以使用C ++ 0x rvalue引用移动语义如果支持,如写),具有我期望split(不同于yours)的行为,并且可以与任何容器。

This avoids all of the problems with iostreams in the first place, avoids extra copies (the stringstream's backing string; plus the temp returned by substr can even use a C++0x rvalue reference for move semantics if supported, as written), has the behavior I expect from split (different from yours), and works with any container.

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

这篇关于方法std :: stringstream可以设置失败/坏位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆