将 IP 或 MAC 地址从字符串转换为字节数组(Arduino 或 C)
Convert IP or MAC address from string to byte array (Arduino or C)
我会将 myString“100.200.300.400”转换为字节数组[4]。 我 "bit" 很困惑,这是对的还是需要我使用 foreach 来读取单个数字?
String myString = "100.200.300.400";
byte myByteArray[4];
myString.getBytes(myByteArray,4);
最后我想打印到数组到串行。这个应该没错。
for (i=0; i<4; i++) {
Serial.print(myByteArray[i]);
Serial.print("."); //delimiter
}
我做错了吗?我得到了 49,48,48,0 !
如果您尝试从 "100.150.200.250"
这样的字符串转换为 { 100, 150, 200, 250 }
这样的字节数组,您需要提取每个数字的字符串表示并将它们转换(解析)为二进制将它们存储在字节数组中之前的表示形式。
您尝试执行此操作的方式只是将字符串的前四个字节(即 "100."
)转换为每个字符的二进制表示形式,结果为 { 49, 48, 48, 0 }
.您可以在 ASCII table.
另请记住,当您将其存储在字节数组中时,它将仅支持 0 到 255 之间的值。
当您在小型微控制器上编程时,我建议不要使用 String
class。当您的程序变得越来越大并且您开始使用大量字符串时,您可能 运行 会遇到麻烦。尝试学习如何使用字符数组,您将避免 运行 进入内存问题。请记住 Arduino 只有 2KB 的 RAM!
这是一个函数,您可以使用 strtoul()
函数进行转换:
void parseBytes(const char* str, char sep, byte* bytes, int maxBytes, int base) {
for (int i = 0; i < maxBytes; i++) {
bytes[i] = strtoul(str, NULL, base); // Convert byte
str = strchr(str, sep); // Find next separator
if (str == NULL || *str == '[=10=]') {
break; // No more separators, exit
}
str++; // Point to next character after separator
}
}
然后您可以像这样调用它来转换 IP 地址(基数 10):
const char* ipStr = "50.100.150.200";
byte ip[4];
parseBytes(ipStr, '.', ip, 4, 10);
或者像这样转换一个 MAC 地址(16 进制):
const char* macStr = "90-A2-AF-DA-14-11";
byte mac[6];
parseBytes(macStr, '-', mac, 6, 16);
您也可以使用 sscanf
,顺便使用 its return value:
byte ip[4];
if (sscanf(mString.c_str(), "%hhu.%hhu.%hhu.%hhu", ip, ip+1, ip+2, ip+3) != 4) {
Serial.print("invalid IP: ");
Serial.println(mString);
}
然而,sscanf
可能并未在所有开发板的库中实现,例如在 esp8266 上,它在 2.4.0 版本中是 yet to be released。
此外,某些版本可能不支持 unsigned char
的 %hhu
说明符,但您可以使用 %u
,将其读入 unsigned long
并检查是否该值不大于 255。