Как преобразовать char[12] в byte[6]
Я пытаюсь преобразовать массив char[12], содержащий Mac-адрес, в byte[6] для использования в методе Ethernet.begin. Я пробовал различные методы из Интернета, но пока безуспешно. Массив символов в настоящее время содержит «A4BDC334688C», и мне нужен массив байтов, содержащий {A4, BD, C3 и т. д.}.
Следующее очень близко к рабочему, с выводом следующего "Файл открыт. А4БДК334688К А4 9Д С3 34 68 6C", где BD неправильно преобразуется в 9D, а 8C становится 68.
#include <SPI.h>
#include <SD.h>
#include <ArduinoJson.h>
byte ByteMacAddress[6]; // ЗАРЕЗЕРВИРОВАННЫЙ MAC-АДРЕС
StaticJsonDocument<200> doc;
int ShotCount = 0;
byte buf[40];
void setup() {
Serial.begin(9600);
//Инициализировать SD-карту для конфигурации
if (!SD.begin(4)) {
Serial.println("initialization failed!");
}
// открываем файл для чтения:
File ConfigFile = SD.open("Config.txt");
if (ConfigFile) {
Serial.println("File Opened.");
} else {
Serial.println("error opening Config.txt");
}
// Десериализовать конфигурацию Json в файле
delay(5);
DeserializationError error = deserializeJson(doc, ConfigFile);
ConfigFile.close();
// Проверяем, успешен ли синтаксический анализ.
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
char* SDMacAddress = doc["MacAddress"];
Serial.println(SDMacAddress);
char arr[12];
strcpy(arr, SDMacAddress);
auto getNum = [](char c){ return c > '9' ? c - 'a' + 10 : c - '0'; };
byte *ptr = ByteMacAddress;
for(char *idx = arr ; *idx ; ++idx, ++ptr ){
*ptr = (getNum( *idx++ ) << 4) + getNum( *idx );
}
//Проверить преобразованные значения байтов.
for( byte b : ByteMacAddress )
Serial.println( b, HEX );
}
void loop(){
// Поддерживать аренду DHCP
//Ethernet.maintain();
//Получить число выстрелов();
delay(500);
}
@BelGaraath, 👍2
Обсуждение2 ответа
Лучший ответ:
Пожалуйста, смотрите комментарии в коде:
// SDMacAdress завершается нулем
// (так и должно быть, потому что вы используете strcp, а не strncp)
// символ обр[12]; вам нужен один дополнительный байт для нуля
char arr[13];
strcpy(arr, SDMacAddress);
auto getNum = [](char c)
{
// вы забыли прописные шестнадцатеричные буквы (AF)
// не используйте сложный код
// лучшие программисты пишут понятный код как минимум ИМХО ;-)
// возможно, вы скопировали его из Интернета
// возвращаем c > '9'? с - 'а' + 10 : с - '0';
if ( c >= '0' && c <= '9' ) return c - '0';
if ( c >= 'a' && c <= 'f' ) return 10 + c - 'a';
if ( c >= 'A' && c <= 'F' ) return 10 + c - 'A';
return 0;
};
byte *ptr = ByteMacAddress;
for(char *idx = arr ; *idx ; ++idx, ++ptr )
{
*ptr = (getNum( *idx++ ) << 4) + getNum( *idx );
}
Я пинаю себя за это, проблема была в верхнем регистре. И вы правы, это скопировано из Интернета, но я также сделал ту же глупую ошибку в своей попытке. Большое спасибо за ваше время и помощь., @BelGaraath
Я должен упомянуть, что у @chrisl была эта идея до меня. Я просто привел пример, как это сделать. Пожалуйста, проголосуйте за его/ее (?) комментарий выше. Я сделал это уже. ;-), @Peter Paul Kiefer
Хотел бы я, чтобы у меня был представитель, чтобы проголосовать за вас всех, увы, я здесь новичок., @BelGaraath
Непонятно, почему вы пытаетесь реализовать это с нуля. Если ваш ввод всегда правильно отформатирован, вы можете выполнить преобразование одним вызовом sscanf
char arr[] = "A4BDC334688C";
byte ByteMacAddress[6];
sscanf(arr, "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
&ByteMacAddress[0],
&ByteMacAddress[1],
&ByteMacAddress[2],
&ByteMacAddress[3],
&ByteMacAddress[4],
&ByteMacAddress[5]);
Конечно, вы также можете реализовать это [более элегантно] через цикл, т.е. sscanf
по одному байту за раз.
- Разобрать mac-строку char* в массив uint8_t
- Как восстановить числовые данные, отправленные Arduino в двоичном виде
- Как преобразовать строку в массив байтов
- Проблемы с преобразованием byte[] в String
- Как преобразовать строку в длинную?
- Как преобразовать время EPOCH во время и дату на Arduino?
- Преобразование строки в IP-адрес
- Установить и извлечь отдельные байты числа (lowByte() и highByte())
Вы видели функцию
strtol(buf, &targetvariable, BASE)
, как она используется в ответе на [этот вопрос](https://arduinoprosto.ru/q/36700/convert-serial-value-into- hex-использование-in-genuino-zero)? Вы можете использовать его для преобразования каждого байта (2 символа) по отдельности или даже - с помощью объединения - преобразовать всю строку сразу., @chrislВ
getnum
вы не учитываете буквы верхнего регистра. Буквы все строчные или все прописные?, @chrislобычно двоичное представление MAC-адреса находится в обратном порядке, чем шестнадцатеричная строка, @Juraj
@chrisl Спасибо также за ваш ответ, я очень ценю всех, кто нашел время, чтобы помочь мне., @BelGaraath