I'm trying to send custom data. But it doesn't seem to work. I can't find a way to parse my string to a unit8_t. I tried to follow other people's solutions but they don't seem to work for me.

// Declaration
uint8_t myData[] = "";

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

This is the error message that I keep getting: Incompatible types in assignment of uint8_t {aka unsigned char}' to 'uint8_t [1] {aka unsigned char [1]} .

  • 1
    What are you attempting to do there? Are you trying to convert a textual representation of a number into an actual number, or place a bit of text into a uint8_t buffer? – Majenko Oct 30 '19 at 16:50
  • So you are constructing a C++ String object from a C-String literal, then retrieve the C-String from it and try to parse a number from it (which it does not contain). Makes totalle sense to me.... – Kwasmich Oct 30 '19 at 16:54
  • @Majenko I am trying to place a bit of text in a uint8_t buffer, because I am trying to send data over the LoRaWAN network. If I declare myData[] as myData[] = "Test data"; It send over the network without compiling errors. When I try to put a string into myData after going through setup and in my loop it doesn't seem to be able to add this as simply as myData = "Custom String"; – Mounir Mehjoub Oct 30 '19 at 16:58
  • What is "custom string".c_str() supposed to mean? In modern C++ you can do "custom string"s.c_str(), but only if you do using namespace std::string_literals; first. – AnT Oct 30 '19 at 19:54

atoi is for converting a textual representation of a number ("123" for example) into an actual integer.

The c_str() function gives you a pointer to the internal buffer of the String (assuming you actually have a String) which is no different to a uint8_t[] or uint8_t * (other than the signedness).

Without knowing exactly what the destination function for this buffer requires it's very hard to help you, but you may want something like:

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

If you need to copy the data into a fixed length buffer then you need to first create a buffer of that actual size - then copy the string data into it:

// Create a buffer of 32 bytes
uint8_t myBuffer[32];
// Copy at most 32 bytes, but no more than there actually is, into the buffer
memcpy(myBuffer, myString.c_str(), min(myString.length(), 32)); 
  • I used your method and deleted the atoi method. I understand the methods a lot more now. I also added a pointer to my declaration variable like uint8_t* myData[2]; – Mounir Mehjoub Oct 30 '19 at 17:13
  • That will actually create an array of two unassigned pointers, not a pointer to an array of 2 bytes. – Majenko Oct 30 '19 at 17:14
  • @MounirMehjoub This might help: majenko.co.uk/blog/arrays-pointers-what-c – Majenko Oct 30 '19 at 17:14

Your code is a mess. It's clear you are badly confused between arrays, pointers, and C++ strings.

When you say

uint8_t myData[] = "";

you make myData of type "array of uint8_t" and make it contain an empty string. You should not then change that value.

When you say

uint8_t *myData;

it means that myData is a variable of type "pointer to uint8_t", but it doesn't point to anything yet.

With that declaration, you can later say:

myData = "custom string";

That points the myData pointer to the address of your constant string. I think that's what you want:

// Declaration
uint8_t *myData;

void loop(){
    myData = "custom string";
  • Yeah, I'm sorry @Duncan C you are right. I'm not really experienced in C++ with pointers. So I tried your resolution but It gave again an error. cannot convert 'String' to 'uint8_t* {aka unsigned char*}' in assignment. What I'm trying to do is convert a custom string to uint8_t so I can send it over LoRaWAN. The method for sending LoRaWAN messages that I use had uint8_t as a parameter. – Mounir Mehjoub Oct 30 '19 at 17:31
  • Re “You should not then change that value”: There is no problem changing that value. Just be aware that it's an array of length 1. – Edgar Bonet Oct 30 '19 at 18:20

Firstly, arrays in C and C++ are not assignable. So, your attempts to assign something to myData array with = operator are bound to fail in any case. Copying data into naked arrays should be done either manually or using library functions.

Secondly, your myData array is declared with size 1. It is just one byte. It is too small to store anything useful. It will not magically "stretch" by itself to accommodate more data. If you need to store more data in that array, it is your responsibility to declare with the appropriate size in advance.

Thirdly, what is "custom string".c_str() supposed to mean??? Something looking very similar to that can be expressed in modern C++ as

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

but I see no reason for that at all. If your input is a C-string, then function atoi is directly applicable to C-strings. No need to convert such C-string to std::string and then back.

Fourthly, atoi is a "dead" function that exists for compatibility with legacy code only. You are not supposed to use atoi in your code. A C-style string-to-number conversion functions are functions from strto... group. E.g. strtol in your case. But in C++ you might have better options, like std::stoi and such.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.