首页 > 解决方案 > Arduino ESP8266 sscanf 可以处理 %lld 吗?

问题描述

我对 Arduino ESP8266 和sscanf功能有疑问。我试图从我从串口收到的字符串中解析一个 64 位整数,如下所示:

int64_t temp_freq = 0;
sscanf(buffer, "FOUT = %lld Hz\r\n", &temp_freq);

编辑:我也试过 `"FOUT = %" SCNd64 " Hz\r\n",结果相同

我知道我从串口得到了正确的字符串,因为我的代码检查我是否收到了特定类型的消息被触发并正在运行。

我还可以确认 %lld 正在使用Serial.printf(),因此我认为它也已实现sscanf

但是,如果字符串中有一个 > 2^31 - 1 的值,我会将 2^31 - 1 写入我的int64_t变量中。因此,例如在我的变量"FOUT = 18010000000 Hz\r\n"中给我 2,147,483,647 。int64_t

是我使用sscanf不正确,还是根本没有在平台上正确实现?

同时,我正在使用以下方法作为解决方法:

int64_t temp_freq = 0;
char temp_buf[30] = {0x00};
sscanf(buffer, "FOUT = %s Hz\r\n", &temp_buf);
for (int i = 0; i < strlen(temp_buf); ++i) {
  temp_freq *= 10;
  temp_freq += temp_buf[i] - '0';
}

但我宁愿使用标准的工作方式和正确的方式来避免我不得不在任何地方维护我的手动解决方案。

PS:我标记为 C++ 和 C,因为它在技术上是 Arduino 上的 C++,但我编写的代码看起来更像 C,并且使用 Csscanf而不是stringstreamC++ 或类似的东西。

标签: c++carduinoscanf

解决方案


它只是没有在平台上正确实施吗?

您的工具链使用 newlib 作为 C 标准库实现,并且很可能您使用的是 nano 版本。Newlib-nano 不long long支持printf/scanf家庭功能。

你可以:

  • 使用完整的 newlib 版本而不是 nano 版本。如果是gcc编译器,请不要传递-specs=nano.specs或传递-lnano给您的编译器选项。
  • 使用不同的标准库或重新编译 newlib 并启用该选项。
  • 自己重新实现所需的功能。

请注意,使用%lldwithint64_t可能在技术上是错误的 - 您应该使用SCNd64from inttypes.h


推荐阅读