让 Linux 和 Windows 都满意的 sscanf 替代方案

Posted

技术标签:

【中文标题】让 Linux 和 Windows 都满意的 sscanf 替代方案【英文标题】:Alternative to sscanf that makes both Linux and Windows happy 【发布时间】: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? 【参考方案1】:

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

【讨论】:

为什么这被否决了?任何投反对票或能理解原因的人,请详细说明。我怀疑这行不通(sscanf_s 需要不同的参数)? sscanf_s 在大多数情况下应该可以正常工作,因为字符串文字存在模板化重载。我想可能有些地方它仍然不起作用,尽管我在使用该定义时还没有遇到任何问题。

以上是关于让 Linux 和 Windows 都满意的 sscanf 替代方案的主要内容,如果未能解决你的问题,请参考以下文章

武汉画册设计如何报价预算多少让人满意

kail VMware 主机ss上网

ffmpeg 声音与 -concat 或 -ss 不同步

2021年年总结:你无法让每个人都满意,甚至是大多数人。

2021年年总结:你无法让每个人都满意,甚至是大多数人。

2021年年总结:你无法让每个人都满意,甚至是大多数人。