【问题标题】:What information is used when parsing a (float) number?解析(浮点)数时使用什么信息?
【发布时间】:2014-05-02 08:44:38
【问题描述】:

C++ 标准库在解析(浮点)数字时使用哪些信息?

这是我知道用 std c++ 解析(单个)浮点数的可能性:

很明显,至少,我们必须知道使用什么字符作为小数分隔符。

iostreams,特别是num_get::get另外也讲一下:

  • ios_base I/O 格式标志 - 这里是否有 任何 用于解析 浮点 的信息?
  • thousands_separator(* 见下文

另一方面,在std::strtod 中,这似乎是sscanf 的定义(又被num_get 引用),唯一的变量信息似乎是@987654327 @ 和十进制字符,尽管似乎没有指定 that 的定义位置。 (至少在 cppref 和 MSDN 上都没有。)

那么,实际使用了哪些信息,以及 C++ 标准库的有效可解析浮点表示形式是什么?

据我所知,只需要全局的小数点分隔符(CC++???),此外,如果数字包含千位分隔符,我希望它只会被解析num_get 正确,因为 strod/sscanf 不支持千位​​分隔符。


(*) 组(千)分隔符对我来说是一个有趣的案例。据我所知,“C”函数并没有任何引用它,上次我检查CC++标准printf函数永远不会写它。那么它真的是由strtod/scanf函数处理的吗? (我知道组分隔符有一个 POSIX printf 扩展,但这并不是真正的标准,而且在 Microsoft 的实现中尤其缺失。)

【问题讨论】:

  • 他们都应该使用当前的语言环境来确定千位分隔符和小数点字符。
  • sscanf(3)(和scanf(3),和fscanf(3),还有strtod(3))是C 函数,提供向后兼容性。他们(作为他们的 C++ 同行)应该尊重语言环境设置。
  • @vonbrand -num_get::get 的定义甚至引用了sscanf。对我来说,它们是完全有效的标准 C++ 函数。
  • @JoachimPileborg - 请参阅我的编辑 wrt。千位分隔符
  • @MartinBa,它们是完全有效的,但 C 遗留/兼容性。即,最好不要使用。

标签: c++ c locale iostream scanf


【解决方案1】:

strtod() 的 C11 规格似乎有一个足够大的开口,任何尺寸的卡车都可以通过。它看起来很开放,我认为没有限制。

§7.22.1.3 6 在“C”语言环境之外,可以接受其他特定于语言环境的主题序列形式。


对于非“标准 C”语言环境,isspace()、小数点(基数)、组分隔符、每组数字和符号似乎构成了典型的变体。但显然没有限制。


为了好玩实验,使用printf()sscanf()strftime()isspace() 使用 500 多个语言环境。

所有测试的语言环境都有一个基数(小数)点 '.'',',相同的 +/- 符号,没有数字分组,以及预期的 0-9。

strftime(... "%Y" ...) 在 1000-99999 年间未使用数字分隔符。

sscanf("1,234.5", "%lf", ..sscanf("1.234,5", "%lf", .. 在任何语言环境中都没有生成 1234.5。

0 到 255 范围内的所有 int 值都会产生相同的 isspace() 结果,但有时会出现 154 和 160 的例外情况。

当然,这些测试并不能证明可能发生的事情的限制,但确实代表了可能性的样本。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
相关资源
最近更新 更多