uint8_t * zu char ?

Ich habe einen Webserver und dort liefert mir das WebSocketEvent payload zurück das als uint8_t * definiert ist.
In java wird der Text "*test1" gesendet. Der kommt auch an. Nun möchte ich aber den * aus payload löschen und den Reststring "Test1" in ein char kopieren, habe aber kein plan wie ich das anstellen soll. Ich könnte uint8_t * in char konvertieren und dort das erste zeichen löschen aber selbst die Konvertierung klappt nicht. u.a.

char * effekt  = payload;

Vielleicht wäre jemand von euch so nett und könnte mir sagen wie das geht. Danke!

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { // When a WebSocket message is received
  switch (type) {
    case WStype_DISCONNECTED:             // if the websocket is disconnected
      Serial.printf("[%u] Disconnected!\n", num);
      break;
    case WStype_CONNECTED: {      
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
      }
      break;
    case WStype_TEXT:                     // if new text data is received
      Serial.printf("[%u] get Text: %s\n", num, payload);
if (payload[0] == '*') { 


Serial.printf("[%u] get Text: %s\n", num, payload);

HIER SOLLTE MEIN CODE ZUR AUSWERTUNG STEHEN. Das * am begin von Payload soll gelöscht werden und in einen Char kopiert werden.

}

  }
}
...
..
.

Balisto:
Vielleicht wäre jemand von euch so nett und könnte mir sagen wie das geht. Danke!

Evtl. verstehe ich Dich falsch, aber hast Du es schon mit

payload[0]='_';

versucht? Dadurch wird der Stern (das erste Zeichen) im char-Array durch einen Unterstrich ersetzt.

Oder meinst Du ein anderes Sternchen?

Gruß

Gregor

Das erste Zeichen soll gelöscht werden.
Am besten wäre es wenn man payload in char konvertieren würde dann hätte ich "Test1" dann das erste zeichen entfernen damit ich "Test1" bekomme.

payload+1 ist der C-String hinter dem * (oder was auch immer).

Du brauchst den * nicht entfernen, du kannst einfach dahinter zeigen (Pointer halt).

Serial.printf("[%u] get Text: %s\n", num, payload + 1);

Super, dass funktioniert!

Wie bekomme ich das Ergebnis nun in eine neue variable char ?

char effekt = payload+1;

funktioniert aber nicht.

In einen Char kannst du einen Char-Array nicht stecken.

Du kannst allerdings, ähnlich wie in deinem Kode, einen Char-Pointer auf das Ende des Strings setzen.

char* effekt = payload + 1;

Der übergebene String ist nur während de Aufrufs gültig, wenn du den Inhalt für später aufheben willst, musst du eine Kopie machen.

Das geht leider nicht da kommt der Fehler:

invalid conversion from 'uint8_t* {aka unsigned char*}' to 'char*' [-fpermissive]

Daran verzweifle ich schon eine ganze weile :frowning:

Ich möchte eine neue Variable in der der rest von payload+1; gespeichert ist, damit ich dies wo anders im Programm auswerten kann.etwa so: If effekt = "Test1" dann...

char* effekt = (char*)payload + 1;

Ein Cast ist ok wenn man weiss was man tut, beseitigt eigentlich nur die Fehlermeldung.

Super! +1 Vielen Dank! Nun funktioniert das endlich.

An die etwas umständliche Definition muss ich mich noch gewöhnen. Falls es dir nicht zu viel ist (oder gerne auch jemand anderes), könntest du mir erklären warum das so definiert werden muss. So ganz verstehe ich das nicht. Danke!!

PS: Schönes Avatarbild. Ich liebe Katzen xD

Balisto:
So ganz verstehe ich das nicht.

Was ich verstehen kann. Eine Fehlermeldung die ungefähr sagt, dass man Rolf (auch als Dieter bekannt) nicht Dieter nennen kann, ist etwas, das in mir den Wunsch weckt, jemandem in den Hintern zu treten.

Fluchen hilft :slight_smile:

Gruß

Gregor

Ein Vorschlag wie man den Text retten könnte

const byte MAXLEN = 10;

char gemerkt[MAXLEN];
char inText[] = "*Taler";

void machKopie(char* in, char* out, byte maxLen) {
  if (*in == '*') {
    in++;
  }
  strncpy(out, in, maxLen - 1);
}

void setup() {
  Serial.begin(250000);
  machKopie(inText, gemerkt, MAXLEN);
  Serial.print(F("inText '"));
  Serial.print(inText);
  Serial.print(F("' gemerkt '"));
  Serial.print(gemerkt);
  Serial.print(F("'\n"));
  strcpy(inText, "Stern");
  Serial.print(F("inText '"));
  Serial.print(inText);
  Serial.print(F("' gemerkt '"));
  Serial.print(gemerkt);
  Serial.print(F("'\n"));
}

void loop() {}
inText '*Taler' gemerkt 'Taler'
inText 'Stern' gemerkt 'Taler'

Balisto:
An die etwas umständliche Definition muss ich mich noch gewöhnen. Falls es dir nicht zu viel ist (oder gerne auch jemand anderes), könntest du mir erklären warum das so definiert werden muss.

char* cPtr;
unsigned char* bPtr;

Beide Variablen zeigen auf Datenstrukturen der Größe 1 (Bytes), lediglich werden diese Bytes anders interpretiert,
wenn sie in arithmetischen Ausdrücken benutzt werden.
Beim Kopieren (oder Ausgeben) spielt das keine Rolle, man kann gefahrlos dem Kompiler mit dem Cast mitteilen,
dass man wirklich meint was man schreibt, nämlich einen Pointer auf uint8_t einem Pointer auf char zuzuweisen.

Meinen Avatar habe ich irgendwo im Netz gefunden, vielleicht tausche ich den mal gegen ein Foto meiner Katze aus.

gregorss:
Was ich verstehen kann. Eine Fehlermeldung die ungefähr sagt, dass man Rolf (auch als Dieter bekannt) nicht Dieter nennen kann, ist etwas, das in mir den Wunsch weckt, jemandem in den Hintern zu treten.

Na ja, in der Fehlermeldung steht - um in deinem Bild zu bleiben - ,
dass man Rolf (auch als Dieter bekannt) nicht Dietmar nennen kann.

Whandall:
Na ja, in der Fehlermeldung steht - um in deinem Bild zu bleiben - ,
dass man Rolf (auch als Dieter bekannt) nicht Dietmar nennen kann.

Dort steht "aka char*" und dass es nicht in char* konvertiert werden kann. Wie kommst Du daher auf Dieter und Dietmar?

Gruß

Gregor

invalid conversion from 'uint8_t* {aka unsigned char*}' to 'char*' [-fpermissive]

char* kommt in beiden vor, wie Diet in Dietmar und Dieter.

Nochmals danke!
Ich habe schon sehr viel in Delphi/Pascal programmiert. Da gibt es auch Pointer usw. Aber das ist immer noch wesentlich einfacher als das Zeugs in C :roll_eyes:

Dein Vorschlag zum retten des Textes benötige ich weil die Variable effekt nicht global machbar ist? Muss das die Tage mal testen.

puhhh... Jetzt brauche ich payload noch als int

Wäre nett wenn noch mal jemand helfen könnte. danke.

Du kannst einen einen Zeiger einfach auf int casten und diesen deferenzieren

void setup()
{
  Serial.begin(9600);
 
  unsigned char data[] = { 0x08, 0x10 };
  int value = *((int*)data);
 
  Serial.println(value);
}

void loop()
{
}

0x1008 = 2064 4104 = 0001 0000 0000 1000

int nach Byte-Array geht analog. Man nimmt die Adresse des Wertes und castet nach byte*

Wenn man beim Auslesen auswählen kann wohin das gespeichert wird ist es aber schöner eine Union aus einem Byte-Array und dem Ziel-Datentypen zu verwenden. Das kann z.B. auch ein Array aus int sein wenn man mehrere Werte übertragen will.

unsigned char data[] = { 0x10, 0x08 };
....
0x1008 = 2064 = 0001 0000 0000 1000

Als kleine Korrektur/Klarstellung:

void setup() {
  Serial.begin(9600);
 
  unsigned char data[] = { 0x10, 0x08 };
  int value = *((int*)data);
 
  Serial.println(value, HEX);  // gibt 810 aus, *(data+1) == 0x08 ist das höherwertige Byte 
}

Und, ganz am Rande, 0x1008 = 0001 0000 0000 1000binär = 410410

Wenn ähnliche Hardware für beide Richtungen verwendet wird, ist es aber egal, ob bei größeren Variablen das niederwertigste oder das höchstwertige Byte in der ersten Speicherstelle steht.

ARG! Stimmt natürlich mit der Wertigkeit :frowning: