C++ 在Arduino上使用sscanf会与const char*不匹配,返回值始终相同,尽管输入值不同

C++ 在Arduino上使用sscanf会与const char*不匹配,返回值始终相同,尽管输入值不同,c++,arduino,scanf,C++,Arduino,Scanf,arduino IDE编译器非常宽容,允许将变量定义为“byte”,即uint8_t或无符号字符,并且似乎可以运行。但是它并没有直接插入这个测试代码。我使用ArduinoIDE和PlatformIO来比较结果。为了调试,我将这个代码插入到OnLeNeBDC++模拟器中。我需要提供表示二进制值的十六进制字节,就像我这样插入: 常量字符s[]={0x37,0x74,0x37,0};//00110111,01110100,00110111,0 WriteTextPackage(个) 我必须将模拟器中的

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

常量字符s[]={0x37,0x74,0x37,0};//00110111,01110100,00110111,0 WriteTextPackage(个)

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

最后,n字节的返回值总是“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)
} 

成功!谢谢你的大力帮助。将“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数之后的十六进制数:

五,


16、A9、69、55、C6、A8成功!谢谢你的大力帮助。将“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数之后的十六进制数:

五,


16、A9、69、55、C6、A8

为什么要将
%x
字节
字符
一起使用?
scanf
%x
必须使用指向
无符号整数
的指针,根据C标准。我怀疑Arduino在这方面有什么不同。您正在传递一个指向
字节的指针,因此它将中断。这就是全部。如果要将十六进制值解析为字符,可以使用
%hhx
。这是Github的公共域代码。它在Uno/Mega板上编译和运行良好,许多人已经使用它好几年了。Arduino IDE中没有警告,但PlatformIO IDE捕获到%x和b之间的不匹配,这是一个带有此警告的“字节”:格式“%x”要求参数类型为“unsigned int*”,但参数8的类型为“byte*{aka unsigned char*}”“。我尝试使用%p而不是%x,尝试将b指定为uint8\u t和未签名字符,但每次更改都只会导致一个硬错误而不是警告。”。我仍然在学习C++,但知道Delphi是类似的。为什么你使用<代码> Byth<代码>或<代码> char < /> >?<代码> SCANF > <代码> %x < /Cord>必须根据C标准取一个指针,指向<代码>未签名的int >。我怀疑Arduino在这方面有什么不同。您正在传递一个指向
字节的指针,因此它将中断。这就是全部。如果要将十六进制值解析为字符,可以使用
%hhx
。这是Github的公共域代码。它在Uno/Mega板上编译和运行良好,许多人已经使用它好几年了。Arduino IDE中没有警告,但PlatformIO IDE捕获到%x和b之间的不匹配,这是一个带有此警告的“字节”:格式“%x”要求参数类型为“unsigned int*”,但参数8的类型为“byte*{aka unsigned char*}”“。我尝试使用%p而不是%x,尝试将b指定为uint8\u t和未签名字符,但每次更改都只会导致一个硬错误而不是警告。”。我还在学习C++,但是知道Delphi是类似的。