【问题标题】:Alternative to sscanf that makes both Linux and Windows happy让 Linux 和 Windows 都满意的 sscanf 替代方案
【发布时间】:2019-02-04 23:30:58
【问题描述】:

我有一个真正古老的punch-card format 和一个使用sscanf 读取它的C++ 代码,如下所示,

   sscanf(longstr1,"%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ",
                   &cardnumb,&satrec.satnum,&classification, intldesg, &satrec.epochyr,
                   &satrec.epochdays,&satrec.ndot, &satrec.nddot, &nexp, &satrec.bstar,
                   &ibexp, &numb, &elnum );

这里字符串longstr1 的前两个字符组成一个int 读入cardnum,接下来的五个字符组成一个int 读入satrec.satnum,依此类推。 (一定年龄的人会认出这是一种 Hollerith 格式。)字符串longstr1 中的字符位置永远不会改变。

这很好用,但我必须让它在 Linux 上与 gcc 和 Windows 上的 Visual Studio C++ (2017) 一起工作。 VS 抱怨 sscanf 不安全(我想是的),并建议将其替换为 sscanf_s,这是 Microsoft 独有的功能。我需要一个让 VS 满意的替代品,但在 Linux 上也可以使用 gcc 编译。

是否有一些安全且可能简单的方法来完成此操作?

【问题讨论】:

  • 当然。这是 C++ 代码,而不是 C。
  • @RodneyPrice sscanf_s 在 C11 中,但不在 C99 中,从不在 C++ 中。
  • 你知道如何使用格式化提取运算符<< 运算符吗?
  • 有什么理由不忽略或禁用警告并继续使用sscanf?潜在的问题是"%10s" 可能比相应的缓冲区长,但如果你知道它不是你没问题。如果您感到偏执并想确保sscanf 代码在程序员更改缓冲区大小时自动调整,请将格式更改为"%*s" 并传入..., sizeof intldesg - 1, intldesg, ...。或者,#ifdef _MSC_VERsscanf_s(...);#elsesscanf(...);#endif
  • 既然这是在 C++ 中使用的,为什么要使用 sscanf() 而不是 C++ 风格的流 I/O?

标签: c++ visual-studio security gcc


【解决方案1】:

如果您在 Windows 上定义 _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES,它将在您编写 sscanf 时使用 sscanf_s。这意味着在 Linux 上代码保持原样工作,在 Windows 上,该功能会自动为您替换为安全版本,但不再生成任何警告,因此两个平台都应该满意。有关详细信息,请参阅 Microsoft 文档网站上的 secure template overloads

【讨论】:

  • 为什么这被否决了?任何投反对票或能理解原因的人,请详细说明。我怀疑这行不通(sscanf_s 需要不同的参数)?
  • sscanf_s 在大多数情况下应该可以正常工作,因为字符串文字存在模板化重载。我想可能有些地方它仍然不起作用,尽管我在使用该定义时还没有遇到任何问题。
猜你喜欢
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
  • 2018-08-07
相关资源
最近更新 更多