我正在解析固定NMEA句子中的GPS状态条目,其中地理分钟的一小部分总是在一段时间之后.但是,在locale将逗号定义为小数分隔符的系统上,atof函数忽略句点和整数小数部分.
处理这个问题的最佳方法是什么?存储在字符数组中的长/纬度字符串,如果重要的话.
示例代码:
m_longitude = atof((char *)pField);
Run Code Online (Sandbox Code Playgroud)
哪里
pField[] = "01000.3897";
Run Code Online (Sandbox Code Playgroud)
跨平台项目,为Windows XP和CE编译.
评论解决方案:
接受的答案更优雅,但这个答案(和评论)也值得快速解决
rjn*_*son 16
你总是可以使用(模数错误检查):
#include <sstream>
...
float longitude = 0.0f;
std::istringstream istr(pField);
istr >> longitude;
Run Code Online (Sandbox Code Playgroud)
标准iostream默认使用全局语言环境(反过来应该初始化为经典(美国)语言环境).因此,除非有人以前将全局语言环境更改为其他内容,否则上述内容应该可以正常工作,即使您在非英语平台上运行也是如此.要确保使用所需的语言环境,请创建一个特定的语言环境,并在读取之前使用该语言环境"填充"该流:
#include <sstream>
#include <locale>
...
float longitude = 0.0f;
std::istringstream istr(pField);
istr.imbue(std::locale("C"));
istr >> longitude;
Run Code Online (Sandbox Code Playgroud)
作为旁注,我通常使用正则表达式来验证NMEA字段,将字段的不同部分提取为捕获,然后使用上述方法转换不同的部分.NMEA经度字段中小数点前面的部分实际上格式化为"DDDMM.mmm ..",其中DDD对应度数,MM.mmm到分钟(但我猜你已经知道了).
我曾经做过的一个讨厌的解决方案是sprintf()0.0f并从输出中获取第二个字符.然后在输入字符串中替换'.' 通过那个角色.这解决了逗号大小写,但如果区域设置定义了其他小数分隔符,也可以使用.
这个问题很老了,但与此同时,在 C++ 中,我们得到了一个“与语言环境无关”的 atof:
std::from_chars(及其兄弟std::to_chars),在 c++17 中添加,提供与语言环境无关的浮点扫描(和格式)。它们位于 header 中<charconv>。
您可以在此处阅读有关它们的更多信息:
https://en.cppreference.com/w/cpp/utility/from_chars
https://en.cppreference.com/w/cpp/utility/to_chars
我推荐 Stephan T. Lavavej 关于这两个工具的精彩演讲,这是他谈论使用 std::from_chars 部分的链接:https ://youtu.be/4P_kbF0EbZM ? t = 1367
我举了一个简短的例子:
#include <charconv>
#include <iostream>
#include <system_error>
int main()
{
char buffer[16] { "123.45678" };
float result;
auto [p, ec] = std::from_chars(std::begin(buffer), std::end(buffer), result);
if(ec == std::errc{})
std::cout << result;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,至于今天 (05.06.2020) 只有 MSVC 支持这些带有浮动类型的函数。有效地实施它们被证明是一个大问题。
@edit (27.04.2021) 今天发布的 libstdc++ 稳定版 GCC 11.1 增加了对 float-type 的支持<charconv>。然而,这个实现似乎不符合标准——它需要将文本复制到另一个缓冲区并strto(f/d/ld)使用默认的 C 语言环境调用并设置浮动环境,从errno. 在极其奇怪的情况下,它可以在下面分配、抛出和捕获异常。你可以在这里找到实现:https :
//github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/src/c%2B%2B17/floating_from_chars.cc#L304