将IP或MAC地址从字符串转换为字节数组(Arduino或C)
问题描述:
我会将myString“100.200.300.400”转换为字节数组[4]。 我是一个“有点”困惑,这是正确的或需要我使用一个foreach读一个单一的数字?将IP或MAC地址从字符串转换为字节数组(Arduino或C)
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
类。当程序变大并且开始使用大量字符串时,您可能会遇到麻烦。尝试学习如何使用字符数组,而不会遇到内存问题。记住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 == '\0') {
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。
此外,%hhu
说明符unsigned char
可能无法在某些版本的支持,但你可以用%u
,读给一个unsigned long
并检查值不大于255
49更大的是ASCII码字符“1”,48是“0”等等。所以你得到了预期的结果。 –
如果你想将它转换为一个字节数组,它听起来像你只是想要的数字。问题是你有两个大于255的数字,你不能将一个大的数字存储到一个字节中。 –
@DavidHoelzer最基本的问题是,OP正在尝试将字符串转换为数字,而不是字符串转换为字节数组。 –