【问题标题】:What should I use instead of sscanf?我应该使用什么来代替 sscanf?
【发布时间】:2010-11-05 05:09:24
【问题描述】:

我有一个 sscanf 解决的问题(从字符串中提取内容)。不过我不喜欢 sscanf ,因为它不是类型安全的,而且又旧又可怕。我想变得聪明,并使用 C++ 标准库的一些更现代的部分。我应该改用什么?

【问题讨论】:

  • 例如因为他说的原因,sscanf 不是类型安全的。
  • @Kaleb Pederson:对于许多说英语的人来说,“聪明”可能只是意味着“聪明”,并且没有它在美国有时具有的负面含义。请注意,Ben Hymers 来自英国。
  • “聪明”有贬义吗?这可能说明了美国。我不确定是什么。是的,我的意思是聪明:)
  • @BenHymers 想想看,是的,在美国,“聪明”有时带有一丝讽刺意味,意思是“有创意,但很顽皮”。以这种方式,自我修改代码可能会被称为聪明。
  • 是的,没错。讨论“聪明”与“聪明”要重要得多:)

标签: c++ scanf c++-standard-library


【解决方案1】:

试试std::stringstream:

#include <sstream>

...

std::stringstream s("123 456 789");
int a, b, c;
s >> a >> b >> c;

【讨论】:

  • 如何知道c是否不存在,例如字符串是“123 456”?
  • @unludo:在这种情况下,c 将不会被修改。您可以使用默认值初始化c,或者您可能需要更复杂的解析。标记器可能会起作用。
  • 从 C++11 开始,c 将被重置为 0,在此之前我相信它的故障后值是未定义的。无论如何,要检查c 是否存在,请使用流状态(为方便起见,来自operator bool()):if (s &gt;&gt; a &gt;&gt; b) if (s &gt;&gt; c ) abc_there(); else ab_there(); else didnt_have_a_and_b();。
【解决方案2】:

对于大多数工作,标准流可以完美地完成工作,

std::string data = "AraK 22 4.0";
std::stringstream convertor(data);
std::string name;
int age;
double gpa;

convertor >> name >> age >> gpa;

if(convertor.fail() == true)
{
    // if the data string is not well-formatted do what ever you want here
}

如果您需要更强大的工具来进行更复杂的解析,那么您可以考虑使用 Regex 甚至 Boost 的 Spirit。

【讨论】:

    【解决方案3】:

    如果您包含sstream,您将可以访问为字符串提供流的stringstream 类,这正是您所需要的。 Roguewave 有一些不错的examples on how to use it.

    【讨论】:

      【解决方案4】:

      如果你真的不想使用流(因为可读性很好),你可以使用 字符串打印。

      你可以在 Folly 中找到它的实现:

      https://github.com/facebook/folly/blob/master/folly/String.h#L165

      【讨论】:

      • 不错的代码(我已经使用了几乎相同的东西),尽管它是 printf 而不是 sscanf 的替代品。
      【解决方案5】:

      fgets 或 strtol

      【讨论】:

        猜你喜欢
        • 2010-12-06
        • 2012-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-06
        • 1970-01-01
        相关资源
        最近更新 更多