我遇到Arduino ESP8266和sscanf
函数的问题。我试图从我从串行端口收到的字符串解析64位整数,如下所示:
int64_t temp_freq = 0;
sscanf(buffer, "FOUT = %lld Hzrn", &temp_freq);
编辑:我也试过' "FOUT = %"SCNd64";Hzrn",结果相同
我知道我从串行端口得到了正确的字符串,因为我的代码检查我是否收到了特定类型的消息被触发并正在运行。
我还可以确认%lld正在与Serial.printf()
一起工作,因此我假设它也适用于sscanf
。
但是,如果我有一个值>2^31 - 1在字符串中,我得到2^31 - 1写入我的int64_t
变量。例如,"FOUT = 18010000000 Hzrn"
在我的int64_t
变量中给出了2,147,483,647。
我使用sscanf
不正确,或者它只是没有在平台上正确实现?
我同时使用以下方法作为解决方法:
int64_t temp_freq = 0;
char temp_buf[30] = {0x00};
sscanf(buffer, "FOUT = %s Hzrn", &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,并使用C的sscanf
而不是stringstream
或类似于c++的东西。
它只是没有在平台上正确实现吗?
你的工具链使用newlib作为C标准库实现,很可能你正在使用它的nano版本。Newlib-nano在printf/scanf
系列函数中不支持long long
。
您可以:
- 使用完整的newlib版本而不是nano版本。在
gcc
编译器的情况下,不传递-specs=nano.specs
或-lnano
到编译器选项。 - 使用不同的标准库或重新编译newlib并启用该选项。
- 重新实现所需的功能。
注意,使用%lld
和int64_t
在技术上可能是错误的-你应该从inttypes.h
使用SCNd64
。