I would convert myString "100.200.300.400" to byte array [4]. I'm a "bit" confused, this is right or need i to use a foreach for reading a single number?
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 !
2 Answers 2
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.
The way you are trying to do this, you are just converting the first four bytes from the string, i.e. "100."
, to the binary representation of each character, which turns out to be { 49, 48, 48, 0 }
. You can look that up in an ASCII table.
Also remember that, as you are storing this on a byte array, it will only support values from 0 to 255.
As you are programming on small microcontroller, I would advise against using the String
class. 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!
Here is a function you can use to make that conversion using the strtoul()
function:
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):
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):
const char* macStr = "90-A2-AF-DA-14-11";
byte mac[6];
parseBytes(macStr, '-', mac, 6, 16);
-
if i have a MAC Address like "90-A2-AF-DA-14-11" could i use the same function? I think not because i don't need the byte conversion (MAC address il already hexadecimal). Wrong?Davide– Davide2016年02月08日 21:56:57 +00:00Commented Feb 8, 2016 at 21:56
-
1@Davide I changed the function a bit to handle different number bases and added an example with a MAC address.Luis Chavier– Luis Chavier2016年02月09日 16:51:39 +00:00Commented Feb 9, 2016 at 16:51
You could also use sscanf
, and by the way detect invalid inputs using 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);
}
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.
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.
atoi
function. And the Arduino'sString
object has some useful methods: arduino.cc/en/Reference/StringObject