Несовместимые типы при назначении «uint8_t {aka unsigned char}» на «uint8_t [1] {aka unsigned char [1]}»

Я пытаюсь отправить пользовательские данные. Но, похоже, это не работает. Я не могу найти способ разобрать мою строку на unit8_t. Я пытался следовать решениям других людей, но они мне не подходят.

// Declaration
uint8_t myData[] = "";


void loop(){
    myData = *(uint8_t*)atoi("custom string".c_str());
}

Это сообщение об ошибке, которое я постоянно получаю: Несовместимые типы при назначении uint8_t {aka unsigned char}' на 'uint8_t [1] {aka unsigned char [1]} .

, 👍0

Обсуждение

Что вы там пытаетесь сделать? Вы пытаетесь преобразовать текстовое представление числа в фактическое число или поместить немного текста в буфер uint8_t?, @Majenko

Таким образом, вы создаете объект C++ String из литерала C-String, затем извлекаете из него C-String и пытаетесь проанализировать из него число (которое он не содержит). Имеет для меня полный смысл...., @Kwasmich

@Majenko Я пытаюсь поместить немного текста в буфер uint8_t, потому что пытаюсь отправить данные по сети LoRaWAN. Если я объявлю myData[] как myData[] = "Test data"; Он отправляет по сети без ошибок компиляции. Когда я пытаюсь поместить строку в myData после прохождения настройки и в моем цикле, похоже, я не могу добавить это так же просто, как myData = "Custom String";, @Mounir Mehjoub

Что означает «пользовательская строка».c_str()? В современном C++ вы можете использовать "пользовательскую строку" s.c_str(), но только если вы сначала используете используя пространство имен std::string_literals;`., @AnT


3 ответа


Лучший ответ:

0

atoi предназначен для преобразования текстового представления числа (например, "123") в фактическое целое число.

Функция c_str() дает вам указатель на внутренний буфер строки (при условии, что у вас действительно есть строка), который ничем не отличается от uint8_t[] или uint8_t * (кроме подписи).

Не зная точно, что требуется функции назначения для этого буфера, очень трудно вам помочь, но вы можете захотеть что-то вроде:

LoRaWan.send((uint8_t *)myString.c_str(), myString.length());

Если вам нужно скопировать данные в буфер фиксированной длины, вам нужно сначала создать буфер этого фактического размера, а затем скопировать в него строковые данные:

// Создаем буфер размером 32 байта
uint8_t myBuffer[32];
// Копируем в буфер не более 32 байт, но не больше, чем есть на самом деле
memcpy(myBuffer, myString.c_str(), min(myString.length(), 32)); 
,

Я использовал ваш метод и удалил метод atoi. Теперь я понимаю методы намного больше. Я также добавил указатель к моей переменной объявления, такой как uint8_t* myData[2];, @Mounir Mehjoub

Это фактически создаст массив из двух неназначенных указателей, а не указатель на массив из 2 байтов., @Majenko

@MounirMehjoub Это может помочь: https://majenko.co.uk/blog/arrays-pointers-what-c, @Majenko


0

В вашем коде беспорядок. Очевидно, вы сильно путаетесь между массивами, указателями и строками C++.

Когда вы говорите

uint8_t myData[] = "";

вы создаете myData типа "массив uint8_t" и содержите пустую строку. В этом случае вам не следует изменять это значение.

Когда вы говорите

uint8_t *myData;

это означает, что myData является переменной типа "указатель на uint8_t", но пока ни на что не указывает.

Этим объявлением вы позже сможете сказать:

myData = "custom string";

Это указывает указатель myData на адрес вашей постоянной строки. Я думаю, это то, что вы хотите:

// Декларация
uint8_t *myData;

void loop(){
    myData = "custom string";
}
,

Да, мне жаль, @Duncan C, ты прав. Я не очень разбираюсь в С++ с указателями. Итак, я попробовал ваше решение, но оно снова дало ошибку. не может преобразовать 'String' в 'uint8_t* {aka unsigned char*}' при назначении. Что я пытаюсь сделать, так это преобразовать пользовательскую строку в uint8_t, чтобы я мог отправить ее по LoRaWAN. Метод отправки сообщений LoRaWAN, который я использую, имел uint8_t в качестве параметра., @Mounir Mehjoub

Относительно «_Вам не следует изменять это значение_»: Нет проблем с изменением этого значения. Просто имейте в виду, что это массив длины 1., @Edgar Bonet


0

Во-первых, массивы в C и C++ нельзя присваивать. Таким образом, ваши попытки присвоить что-то массиву myData с оператором = обречены на провал в любом случае. Копирование данных в голые массивы следует выполнять либо вручную, либо с помощью библиотечных функций.

Во-вторых, ваш массив myData объявлен с размером 1. Это всего лишь один байт. Он слишком мал, чтобы хранить что-то полезное. Он не будет волшебным образом «растягиваться» сам по себе, чтобы вместить больше данных. Если вам нужно хранить больше данных в этом массиве, вы обязаны заранее объявить соответствующий размер.

В-третьих, что означает "custom string".c_str()??? Что-то очень похожее на это может быть выражено в современном C++ как

#include <string>
...
using namespace std::string_literals;
"custom string"s.c_str();

но я вообще не вижу для этого причин. Если вы вводите C-строку, то функция atoi напрямую применима к C-строке. Нет необходимости преобразовывать такую C-строку в std::string и обратно.

В-четвертых, atoi — это «мертвая» функция, которая существует только для совместимости с устаревшим кодом. Вы не должны использовать atoi в своем коде. Функции преобразования строки в число в стиле C — это функции из группы strto.... Например, strtol в вашем случае. Но в C++ у вас могут быть варианты получше, например std::stoi и тому подобное.

,