【问题标题】:Can you tell iostreams which characters to treat as whitespace?你能告诉 iostreams 哪些字符被视为空格吗?
【发布时间】:2010-12-11 22:41:24
【问题描述】:

这样你就可以做这样的事情,例如:

std::string a("01:22:42.18");
std::stringstream ss(a);
int h, m, s, f;
ss >> h >> m >> s >> f;

这通常需要将字符串格式化为"01 22 42 18"。 您可以直接修改当前语言环境来执行此操作吗?

【问题讨论】:

  • 我猜你做不到。有趣的问题虽然 +1

标签: c++ string iostream


【解决方案1】:

我不认为您可以在不创建新语言环境的情况下更改默认分隔符,但这似乎很老套。您可以使用 getline 和指定分隔符的第三个参数,或者您可以读取分隔符而不对它们做任何事情(例如 ss >> h >> d >> m >> d >> s >> d >> f)。

您还可以编写自己的解析类来处理拆分字符串。或者更好的是,使用 Boost 的 String Algorithms Library 中的 boost::split

【讨论】:

  • boost::splitgetline 的烦人之处在于,您必须拆分字符串,然后将它们返回到流中以获取整数
  • 您可以使用boost::splitstd::string 转换为std::vector<std::string>,然后使用std::transformboost::lexical_caststd::vector<std::string> 转换为std::vector<unsigned int>
【解决方案2】:

您可以通过创建一个带有将: 分类为空格的 ctype facet 的语言环境来做到这一点。

Jerry Coffin explains how you can specify whitespace characters in this answer to another question.

【讨论】:

  • 谢谢,这就是我的问题的字面答案!虽然我想弄清楚你是否可以做一个 rc[':'] = std::ctype_base::space;无需创建全新的语言环境...
  • 不幸的是,由于 ios_base 将字符分类为基于灌输语言环境的空白,我认为没有任何其他选择。 Firas 对 boost::split(或者 boost::tokenizer)的建议可能是你的下一个最佳选择。
【解决方案3】:

看看scanffscanf。您可能*能够执行以下操作:

int h, m, s, f;
sscanf(a.c_str(), "%d:%d:%d.%d", &h, &m, &s, &f);  

* 警告:我和 C++ 已经有一段时间了

【讨论】:

  • 对,使用 C 的 scanf 而不是 C++ 的 istream::operator>> 肯定要容易得多。不过,您的意思可能是 sscanf(a.c_str(), "%d:%d:%d.%d", &h, &m, &s, &f) == 4
  • 谢谢,这是一个实用的解决方案。
  • @ehemient 是的,就是这样。就像我说的那样,我已经有一段时间没有接触任何 C/C++ @henle 如果这是您的解决方案,那么将其标记为答案伴侣;)
  • 好的,贾斯汀,因为你问得很好,但其他建议也很好! ;)
【解决方案4】:
char c;
if (!(ss >> h >> c) || c != ':') return;
if (!(ss >> m >> c) || c != ':') return;
if (!(ss >> s >> c) || c != '.') return;
if (!(ss >> f) || ss >> c) return;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多