sscanf() 的更安全但易于使用且灵活的 C++ 替代方案

2024-02-23

当我需要从一堆字符串中扫描值时,我经常发现自己又回到了 C 语言sscanf()严格来说是因为它的简单性和易用性。例如,我可以非常简洁地从字符串中提取几个双精度值:

string str;
double val1, val2;
if (sscanf(str.c_str(), "(%lf,%lf)", &val1, &val2) == 2)
{
    // got them!
}

这显然不是很 C++。我不一定认为这是令人厌恶的,但我一直在寻找更好的方法来完成常见任务。我知道读取字符串的“C++ 方式”是istringstream,但是处理上面格式字符串中的括号和逗号所需的额外输入只会使其变得太麻烦而使我不想使用它。

有没有一种好方法可以以类似于上述的方式将内置设施弯曲到我的意愿,或者是否有一个好的 C++ 库以更类型安全的方式执行上述操作?看起来 Boost.Format 确实以一种很好的方式解决了输出问题,但我还没有找到任何类似的简洁输入。


我编写了一些可以读取字符串和字符文字的代码。与普通流读取一样,如果它获取无效数据,则会设置流的 badbit。这应该适用于所有类型的流,包括宽流。将此位粘贴到新标头中:

#include <iostream>
#include <string>
#include <array>
#include <cstring>

template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&sliteral)[N]) {
        std::array<e, N-1> buffer; //get buffer
        in >> buffer[0]; //skips whitespace
        if (N>2)
                in.read(&buffer[1], N-2); //read the rest
        if (strncmp(&buffer[0], sliteral, N-1)) //if it failed
                in.setstate(in.rdstate() | std::ios::failbit); //set the state
        return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& cliteral) {
        e buffer;  //get buffer
        in >> buffer; //read data
        if (buffer != cliteral) //if it failed
                in.setstate(in.rdstate() | std::ios::failbit); //set the state
        return in;
}
//redirect mutable char arrays to their normal function
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
        return std::operator>>(in, carray);
}

这将使输入字符变得非常容易:

std::istringstream input;
double val1, val2;
if (input >>'('>>val1>>','>>val2>>')') //less chars than scanf I think
{
    // got them!
}

概念验证 http://ideone.com/IVW7v。现在你可以cin字符串和字符文字,如果输入不完全匹配,它的行为就像无法正确输入的任何其他类型一样。请注意,这仅匹配字符串文字中不是第一个字符的空格。它只有四个功能,而且都简单得脑残。

EDIT

使用流进行解析是一个坏主意。使用正则表达式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sscanf() 的更安全但易于使用且灵活的 C++ 替代方案 的相关文章

随机推荐

  • R 闪亮应用程序的 twitter bootstrap 弹出窗口 - html 被解释为文本内容 - 为什么?

    我想将 Twitter 引导框架中的弹出窗口添加到闪亮的应用程序中 一切正常 除了 认为html true标签没有效果 shinyUI pageWithSidebar headerPanel Header sidebarPanel acti
  • 如何跟踪服务 firebird

    如何使用delphi xe10跟踪服务firebird服务器的所有事件 这是我的代码 my TIBControlService Create Self my ServerName 127 0 0 1 3050 my Protocol TPr
  • Subversion 快速解决所有冲突

    当我遇到多个冲突时 有没有办法通过告诉 SVN 保留存储库中的版本来解决所有冲突 不幸的是 我们仍在使用 1 4 我相信如果你运行命令svn revert R 您基本上撤消了对工作副本的所有更改 如果存在冲突的文件 SVN 会放弃您的更改并
  • 使用时初始化缓存

    假设我有以下事件 做一点事 取东西 获取成功的东西 DoSomething做一些需要一些缓存数据的事情 当我触发事件时 我想查看缓存并对其执行某些操作 如果存在 如果没有 那么我想获取它 等待它进入缓存 然后重试 我想出了以下解决方案 但感
  • 在 C 中以均匀概率有效地从文本文件中选择随机行?

    这本质上是一个更受限制的版本这个问题 https stackoverflow com questions 232237 whats the best way to return a random line in a text file us
  • 3d -> 1D 数组索引

    在 C 中 W H D 大小的 3D 数组的索引值是多少 对于特定的 i j k 这是正确的索引 i 宽 高 j 宽 k 您所编写的内容相当于执行以下操作的指针算术 T x D H W x i j k Pointer arithmetic
  • 将数据发送到后台运行的活动

    在活动之间传递数据时遇到问题 ListActivity 正在收集数据 当按下后退按钮时返回到 MainActivity 然后想要通过 onResume 方法获取该数据 但我什么也没得到 如何解决这个问题呢 列表活动 java Overrid
  • Git 在结帐时更改我的文件权限

    我们的工作流程是在本地计算机上开发 将更改提交到中央存储库 然后检查我们需要的该存储库的分支 问题是 Git 会根据签出的用户更改其签出的文件的所有权甚至文件权限 这样做的直接结果是 我们的 CSS 文件在签出后变得不可读 因为 Git 将
  • 使用 C# 命令行 GPG 解密 - 密码?

    我正在使用命令行来加密我发送的文件 但我正在尝试找出如何使用相同的方法来解密它们 如果我运行该命令 系统会提示输入密码 但我看不到使用命令行传递密码的方法 这是我加密文件的方法 var proc new Process proc Enabl
  • 如何从计算引擎访问谷歌驱动器

    我以前没有使用过 GCE 但计划将其用于一些 CPU 绑定的 R 脚本 我看到定价的网络部分说谷歌驱动器有免费的出口和入口 我没有看到任何有关如何从 GCE 中访问我的 google 驱动器的文档 有人可以向我指出这方面的文档吗 我建议使用
  • 两个相同的unordered_map的顺序是否相同?

    换句话说 如果我填两个unordered map or unordered set 具有完全相同内容和相同哈希函数的对象 迭代它们会给出相同的键 值对序列吗 如果是这样 那么它成立的条件是什么 例如相同的散列函数 相同的键 不一定是相同的值
  • 检查两个 DecimalUpDown 控件之间的有效值 - MVVM

    我的窗口中有两个 DecimalUpDown 控件 一个应显示文本框的最大值 另一个应显示最小值 最小控制值不能大于最大控制值 反之亦然 请注意 红色值是错误的 我怎样才能实现这个 我正在使用 MVVM 模式 谢谢 史蒂夫 您应该在视图模型
  • 在 ggplot2 的图中添加一个指向 x 轴的箭头

    我的目标是获得一个带有指向 x 轴的文本的箭头来标记平均词频 我一生都无法弄清楚如何在 ggplot2 中的绘图区域之外获取箭头或文本 这是我的代码 ggplot SUMMARY PCTDIFF aes principle pctdiff
  • MySQL 错误代码:1064。您的 SQL 语法有错误

    真的 可能有什么问题吗 它并没有变得更简单 整个查询 line 1 use foo line 2 line 3 select from test table 1 错误代码 您的 SQL 语法有错误 查看对应的手册 到您的 MySQL 服务器
  • CGEventTapCreate 因“按键按下”事件而神秘崩溃

    我在用着CGEventTapCreate当我的应用程序运行时 从 iTunes 中 窃取 媒体密钥 我传递给的回调内部的代码CGEventTapCreate检查该事件 如果发现它是媒体键之一 则将适当的通知发布到默认通知中心 现在 如果我发
  • C#:如何比较字典值?

    我有一个Dictionary
  • 在 React 应用程序中添加 add sass/scss 的最佳方法是什么?

    我发现 create react app 文档建议使用 node sass 但 npm 中的包说 LibSass 和 Node Sass 已弃用 那么 如果有人可以提供帮助 那么在 React 项目中安装 sass 的最佳方法是什么 我一直
  • 用于客户端层单元测试的模拟 Web 服务

    我有一个业务规则 Visual Studio 类库 NET 2 0 项目 它依赖于 Dynamics Crm Web Services 一个经典的 SOAP Web 引用 而不是 WCF 端点 我想对这些业务规则进行单元测试 而无需背后有真
  • 删除加权有向图中的循环

    这是我其他帖子的后续问题 具有大小约束的聚类算法 https stackoverflow com questions 30112428 algorithm for clustering with size constraints 我正在研究
  • sscanf() 的更安全但易于使用且灵活的 C++ 替代方案

    当我需要从一堆字符串中扫描值时 我经常发现自己又回到了 C 语言sscanf 严格来说是因为它的简单性和易用性 例如 我可以非常简洁地从字符串中提取几个双精度值 string str double val1 val2 if sscanf s