I know that this is old, but I've got a similar routine for Bluetooth addresses. I added a regex filter to make sure the text is the correct format before I parse it.
The reverse order of bytes in this was important because it matches what's produced by the function in the Bluetooth library: int str2ba(const char *str, bdaddr_t *ba);
My new Bluetooth code talks to Bluetooth using an alternate method, but I wanted to keep the internal structure of the Bluetooth address matching.
#include <iomanip>
#include <iostream>
#include <regex>
#ifndef bdaddr_t
/* BD Address */
typedef struct {
uint8_t b[6];
} __attribute__((packed)) bdaddr_t;
#endif // !bdaddr_t
const std::regex BluetoothAddressRegex("((([[:xdigit:]]{2}:){5}))[[:xdigit:]]{2}");
bdaddr_t string2ba(const std::string& TheBlueToothAddressString)
{
bdaddr_t TheBlueToothAddress({ 0 });
if (std::regex_match(TheBlueToothAddressString, BluetoothAddressRegex))
{
std::stringstream ss(TheBlueToothAddressString);
std::string byteString;
int index(5);
// Because I've verified the string format with regex I can safely run this loop knowing it'll get 6 bytes
while (std::getline(ss, byteString, ':'))
TheBlueToothAddress.b[index--] = std::stoi(byteString, nullptr, 16);
}
return(TheBlueToothAddress);
}
std::istringstreamalong with thehexI/O manipulator, and use:as delimiter, to read in the equivalent numbers into a 6 byte array.std::getline()allows to specify an alternate delimiter).