简体   繁体   English

将IP或MAC地址从字符串转换为字节数组(Arduino或C)

[英]Convert IP or MAC address from string to byte array (Arduino or C)

I would convert myString "100.200.300.400" to byte array [4]. 我会将myString“100.200.300.400”转换为字节数组[4]。 I'm a "bit" confused, this is right or need i to use a foreach for reading a single number? 我是一个“有点”困惑,这是对的还是我需要使用foreach来读取一个数字?

String myString = "100.200.300.400";
byte myByteArray[4];
myString.getBytes(myByteArray,4);

Finally I want to print to the array to serial. 最后我想将数组打印到串口。 This should be right. 这应该是正确的。

for (i=0; i<4; i++) {
  Serial.print(myByteArray[i]);
  Serial.print("."); //delimiter
}

Were I am going wrong? 我错了吗? I got 49,48,48,0 ! 我有49,48,48,0!

If you are trying to get from a string like "100.150.200.250" to a byte array like { 100, 150, 200, 250 } , you need to extract the string representation for each number and convert (parse) them into a binary representation before storing them in the byte array. 如果您尝试从像"100.150.200.250"这样的字符串到{ 100, 150, 200, 250 } "100.150.200.250" { 100, 150, 200, 250 }类的字节数组,则需要提取每个数字的字符串表示形式并将它们转换(解析)为二进制表示形式在将它们存储在字节数组中之前。

The way you are trying to do this, you are just converting the first four bytes from the string, ie "100." 你尝试这样做的方式,你只是转换字符串中的前四个字节,即"100." , to the binary representation of each character, which turns out to be { 49, 48, 48, 0 } . ,到每个字符的二进制表示,结果证明是{ 49, 48, 48, 0 } You can look that up in an ASCII table . 你可以在ASCII表中查找

Also remember that, as you are storing this on a byte array, it will only support values from 0 to 255. 还要记住,当您将其存储在字节数组上时,它只支持0到255之间的值。

As you are programming on small microcontroller, I would advise against using the String class. 当你在小型微控制器上编程时,我建议不要使用String类。 You might run into trouble when your programs get bigger and you start using lots of strings. 当程序变大并开始使用大量字符串时,您可能会遇到麻烦。 Try to learn how to use character arrays instead and you will avoid running into memory issues. 尝试学习如何使用字符数组,避免遇到内存问题。 Remember the Arduino has just 2KB of RAM! 记住Arduino只有2KB的RAM!

Here is a function you can use to make that conversion using the strtoul() function: 这是一个函数,您可以使用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
    }
}

You can then call it like this to convert an IP address (base 10): 然后,您可以像这样调用它来转换IP地址(基数为10):

const char* ipStr = "50.100.150.200";
byte ip[4];
parseBytes(ipStr, '.', ip, 4, 10);

Or like this to convert a MAC address (base 16): 或者像这样转换MAC地址(基数为16):

const char* macStr = "90-A2-AF-DA-14-11";
byte mac[6];
parseBytes(macStr, '-', mac, 6, 16);

You could also use sscanf , and by the way detect invalid inputs using its return value : 您还可以使用sscanf ,并使用其返回值检测无效输入:

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);
}

However, sscanf may not be implemented in the library for all boards, for example on esp8266 it's yet to be released in version 2.4.0. 但是, sscanf可能不会在库中为所有板实现,例如在esp8266上它尚未在2.4.0版本中发布

Also, the %hhu specifier for unsigned char may be not supported in some versions, but you can use %u , read it to an unsigned long and check if the value isn't greater than 255. 此外,某些版本可能不支持unsigned char%hhu说明符,但您可以使用%u ,将其读取为unsigned long并检查该值是否不大于255。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM