【问题标题】:Using sscanf on an Arduino gives a mismatch with const char * and return value always the same despite different values for the input在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
【发布时间】:2020-02-12 03:42:55
【问题描述】:

arduino IDE 编译器非常宽容,允许将变量定义为“字节”,即 uint8_t 或无符号字符,并且它似乎可以运行。但它不会直接插入此测试代码。我正在使用 Arduino IDE 和 PlatformIO 来比较结果。为了调试,我将此代码插入 OnlineGBD C++ 模拟器。我需要提供代表二进制值的十六进制字节,就像我这样插入它一样:

const char s[] = { 0x37, 0x74, 0x37, 0 } ; // 00110111,01110100,00110111,0 writeTextPacket(s)

我必须将模拟器中的“byte b[6]”更改为“char b[6]”以使其运行,但 printf 看起来像是给了我指针,而不是内存位置中的内容。我的第二个 Printf 尝试将“b”变量格式化为 %p 以及 %x 以进行测试,并且在值前面添加 0x7ffe,因此 (void**)b 是 0x7ffexxxxxxxx,b 的值是 xxxxxxxx。

最后,nBytes 的返回值始终为“7”。它显然应该给我它找到的字节数。我想我在指针和字符之间感到困惑。谢谢。

void RegisterList::writeTextPacket(const char *s) volatile{

  int nReg;
  byte b[6];
  int nBytes;
  nBytes=sscanf(s,"%x %x %x %x %x %x",&nReg, b, b+1, b+2, b+3, b+4)-1;  // return number of bytes

  printf("%d\n",nBytes);
  printf("%d, %p, %x, %x, %x, %x, %x", nReg, (void**) b, b, b+1, b+2, b+3, b+4);

  loadPacket(nReg,b,nBytes,0,1);  // loadPacket(int nReg, byte *b, int nBytes, int rep, int flag)
} 

【问题讨论】:

  • 你为什么将%x与byte或char一起使用?
  • scanf 和 %x 必须采用指向 unsigned int 的指针,根据 C 标准。我怀疑 Arduino 在这方面有什么不同。您正在传递一个指向byte 的指针,所以它会中断。就这样。如果要将十六进制值解析为char,可以使用%hhx。
  • 这是来自 Github 的公共域代码。它在 Uno/Mega 板上编译和运行都很好,很多人已经使用它好几年了。 Arduino IDE 中没有警告,但 PlatformIO IDE 捕捉到 %x 和 b 之间的不匹配,这是一个带有此警告的“字节”:格式 '%x' 需要类型为 'unsigned int*' 的参数,但参数 8 有type 'byte* {aka unsigned char*}' "。我尝试使用 %p 而不是 %x,尝试将 b 指定为 uint8_t 和 unsigned char,但每次更改都会导致硬错误而不是警告。我还在学习C++,但知道 Delphi 是类似的。

标签: c++ arduino scanf


【解决方案1】:

成功!感谢您的大力帮助。将“byte”更改为“uint8_t”(Arduino 有一个“typdef uint8_t byte”来处理这个问题)并用 %hhx 代替 %x 消除了警告。而这个测试代码:

  const char *s="16 A9 69 55 C6 A8";
  int nReg;
  uint8_t b[6];
  int nBytes;
  nBytes=sscanf(s,"%d %hhx %hhx %hhx %hhx %hhx",&nReg, b, b+1, b+2, b+3, b+4)-1;  // return number of bytes

  printf("%d\n",nBytes);
  printf("%d, %X, %X, %X, %X, %X", nReg, *b, *(b+1), *(b+2), *(b+3), *(b+4));

给出这个正确的结果并只计算整数 nReg 数字之后的十六进制数字:

5

16、A9、69、55、C6、A8

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-06
    • 2021-08-02
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 2020-01-20
    相关资源
    最近更新 更多