converting char arrays in int, float, string

OP (Firma: Herr) #4410453
Lesenswert?

Hi,

und wieder eine Herasuvorderung :-)

habe es geschafft, doch ich frage nach einem eleganteren Weg, da ich 
kein Programmierer bin...

Ich habe Payload welches als byte* kommt, to int/float so umgewandelt:
1
//**********
2
int i;
3
for (i = 0; i<length; i++) {
4
message_buff[i] = payload[i];
5
}
6
message_buff[i] = '\0';
7
const char *p_payload = message_buff;
8

9
//********** converting array to int and float
10
got_double = strtod(p_payload, NULL);
11
got_int = atoi(p_payload);
12
got_float = atof(p_payload);
13
if (got_int == 0 || got_int<0) {
14
got_bool = 0;
15
}
16
else { got_bool = 1; }
17
//**********
danach habe ich Payload was so kommt xxx/sdfdfdjh/lksdfkd/sdjsdhf...

 in ein const char * umgewandelt, weil p_p wird als const char* erwartet 
wird
1
PubSubClient::publish(const char* topic, const char* payload, boolean retained) {
2
    return publish(topic,(const uint8_t*)payload,strlen(payload),retained);

hier die umwandlung:
1
//*******convert float value to Char expected by function
2
char temp[5];
3
dtostrf(rrr,4,3,temp); //rrr ist a float value
4
//*******************
5

6
for (i = 0; i<length; i++) {
7
p_buff[i] = p[i];
8
}
9
p_buff[i] = '\0';
10
const char p_p = p_buff; //
11
MQTTclient.publish(p_p, CHAR);
12
//*********

Velleicht kennt Ihr einen einfacheren und ELLEGANTEREN Weg es zu 
konvertieren?

Danke!

Thank you in Advance!
#4410648
Lesenswert?

Max M. schrieb:
> ELLEGANTEREN

Eleganter wäre es, erstmal lesbaren Quelltext zu schreiben.
Bei dem oben springen ja die Frösche aus dem Teich. Ich lese sowas gar 
nicht im Detail - kann ja nichts taugen, wenn sich jemand sowenig Mühe 
gibt.

Davon abgesehen:

- Wieso konvertierst du in alles mögliche? Zuviel Rechenzeit? Oder 
brauchst du das wirklich?

- Wenn ich von irgendwo eine Zeichenkette bekomme, würde ich mich als 
erstes dafür interessieren, ob überhaupt etwas sinnvolles in einem 
korrekten Format drinsteht, und nicht einfach unreflektiert nach 
irgendwas umwandeln.
Was soll ich mit einer double, wenn der Text "Hilfe" war?
OP (Firma: Herr) #4410693
Lesenswert?

Da muss ich dir recht geben... aber bis jetzt habe ich nur das:
1
void callback(char* topic, byte* payload, unsigned int length) {
2
  //START********************************Convert Calback to int float and bool*************************************** 
3
  Serial.print("Message arrived [");
4
  Serial.print(topic);
5
  Serial.print("] ");
6
  Serial.print("Length:");
7
  Serial.println(length);
8
  Serial.print("Payload:");
9
  Serial.write(payload, length);
10
  Serial.println();
11

12
 //********** Copy the payload to the new buffer 
13
  byte* p = (byte*)malloc(length);
14
  memcpy(p,payload,length);
15
 //********** needs because payload is not deleted 
16
  
17
  
18
  char message_buff[length];
19
  char p_buff[length];
20
  double got_double;
21
  int got_int;
22
  float got_float;
23
  bool got_bool;
24

25
  int i, len;
26

27
  for (i = 0; i<length; i++) 
28
  {
29
    message_buff[i] = payload[i];
30
  }
31
  message_buff[i] = '\0';
32
  const char *p_payload = message_buff;
33

34
  Serial.println("p_payload");
35
  Serial.println(p_payload);
36

37
  got_double = strtod(p_payload, NULL);
38
  got_int = atoi(p_payload);
39
  got_float = atof(p_payload);
40
  if (got_int == 0 || got_int<0) {
41
    got_bool = 0;
42
  }
43
  else { got_bool = 1; }  
44
  Serial.println("BUFF");Serial.println(p_payload);
45
  Serial.println("FLOAT");Serial.println(got_float);
46
  Serial.println("INT");Serial.println(got_int);
47
  Serial.println("BOOL");Serial.println(got_bool);
48
 //**********convert float value to Char expected by function
49
  char temp[5];
50
  dtostrf(rrr,4,3,temp); //rrr ist a float value
51

52
//**********************  
53
  for (i = 0; i<length; i++) {
54
    p_buff[i] = p[i];
55
  }
56
  p_buff[i] = '\0';
57
  const char *p_p = p_buff; //p_p ist topic made from last payload
58
  Serial.println("p_p");
59
  Serial.println(p_p);
60
//  Serial.write(p,length);
61
//  MQTTclient.publish(p_p, temp);
62
//**********************
63
free(p);

Weiss halt noch nicht wie ich am paylaod erkennen kann was das für ein 
tyüe ist... sind ja "nur" bytes (byte array...
Hast du da einen Tipp???


Danke!
#4410717
Lesenswert?

Max M. schrieb:
> Weiss halt noch nicht wie ich am paylaod erkennen kann was das für ein
> tyüe ist... sind ja "nur" bytes (byte array...
> Hast du da einen Tipp???

Dafür definiert man sich normalerweise ein Protokoll (oder nutzt ein 
existierendes). Das legt genau fest, wann welche Daten übertragen werden 
bzw. schickt die relevanten Infos mit, so dass man nicht beim Empfang 
raten muss, was man da wohl gerade empfangen haben könnte.
Um was mit den Daten anfangen zu können, musst du doch eh die Bedeutung 
kennen, und dann ergibt sich der Typ doch schon meist daraus.
Also was ist es, was du da empfängst?
Gast #4410719
Lesenswert?

Ein serielles Protokoll mit variablem Inhalt, liefert auch eine 
Information mit die es erlaubt den Inhalt zu identifizieren.

Das kann sich aus der Länge ergeben
oder  z.B durch ein Schlüsselzeichen
Gast #4410740
Lesenswert?

zuerst musst du prüfen ob generell etwas gekommen ist das dem Protokoll 
entspricht. oder ob der Empfang gestört war.

Dann überprüfst du ob du der richtige Empfänger bist
in dem Beispiel: DOino_01  am Anfang bis zum ersten /

Die Nutzdaten sind in dem Beispiel auch einfach zu finden
kommen direkt nach dem Doppelpunkt


Bool   enthalten nur 0 oder 1
Float  einen Punkt

Wie Int "1" sich vom Bool unterscheiden kann ich an dem Beispiel nicht 
sagen


Konvertierungen von Ascii nach Zahlen benötigen sehr viel Rechenzeit
und macht man nur wenn man es muss.

Zeichenvergleich und Suche geht schnell
Gast #4410761
Lesenswert?

Ich kenne das Protokoll nicht und das eine Beispiel zeugt es nicht

aber das westliche Merkmal einer Floatzahl ist der Punkt oder auf 
deutsch die Kommastelle.
 Es gibt natürlich viele Möglichkeiten diese Information zu übertragen.
#4411325
Lesenswert?

Hallo Max Maxov,

offensichtlich geht es dir um Deserialisierung: 
https://en.wikipedia.org/wiki/Serialization

Also, ein Sender erstellt bspw. aus C-Skalaren (int, float, etc.) ein 
Byte-Array, überträgt dieses Array an den Empfänger, der daraus wieder 
die C-Skalare zurückgewinnt.

Um das Umzusetzen, gibt es sehr viele Möglichkeiten.

Deinem Quelltext nach zu urteilen, serialisierst du deine Daten als 
ASCII String. Das ist absolut ok. Du mußt noch entscheiden wie genau 
dieser ASCII-String aufgebaut sein soll: Wie sieht die Repräsentation 
der einzelnen Skalare in ASCII aus, und, ggf., wie sieht eine Liste von 
Skalaren aus?

Nehmen wir einen ganz einfachen Fall: Es wird lediglich ein Boolean 
übertragen. True als '1' (ASCII 0x31) und False als '0' (0x30). Die 
Nachricht ist somit immer genau ein Byte lang.

Jetzt kommst du. Was möchtest du da übertragen? Welche Kombinationen 
gibt es? Deinen Quelltext nach zu urteilen möchtest du entweder ein 
float, double, int oder boolean übertragen. Häufig benutzt man in diesem 
Fall ein Wertepaar: ein Diskriminator, der anzeigt um welchen Datentyp 
es sich handelt, und dann den Wert selbst.

Die Kodierung des Boolean ist simpel (wie bspw. oben gezeigt). Bei int, 
float und double gibt es allerdings ein paar Fallstricke...
Beitrag #6839101 wurde von einem Moderator gelöscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren