Strings oder Chars unbestimmter Länge zusammenfügen

Hallo,
ich möchte Strings oder Chars unbestimmter Länge zusammenfügen und bekomme das nicht hin.
Im Prinzip ist es so gemeint:

void TEST(char* Temp1, char* Temp2){
  char* Temp = "Text" + Temp1 + "Text" + Temp2;
  Serial.print(Temp);

Wie bekomme ich das hin?

Mit char Arrays bekommst Du das so nicht hin. Die können auch nicht „unbestimmt“ sein.

Vielleicht hilft Dir das hier weiter:

Bedenke aber, dass die Nutzung von String, gerade bei wenig Speicher, problematisch sein kann (Stichwort Speicherfragmentierung). Es ist empfehlenswert sich Gedanken über den maximalen Speicherplatz der Strings zu machen und reserve() zu verwenden.

Also irgendwo sollte doch etwas „bestimmt“ sein.

für c-strings /char Arrays könntest du

strcat

verwenden

Hallo Kai,
danke für den Tipp.
Ich habe jetzt Strings verwendet und mit der Reserve funktioniert es :slight_smile:

Für sowas verwende ich gerne snprintf, weil man damit nicht nur Zeichenketten zusammenfügen kann, sondern auch Zahlen formatiert bekommt. Etwas Einarbeitung ist wegen der vielen Möglichkeiten allerdings unerläßlich.

char text1[20] = {"Start"};
char text2[] = {"Ende"};

void setup()
{
  Serial.begin(9600);
  Serial.println(F("\nStart"));
  ausgabe(text1, text2);
  strcpy(text1, "Neuer Start");
  ausgabe(text1, text2);
}

void ausgabe(char* t1, char* t2)
{
  const char t3[] = "Text ";
  const char t4[] = " Text ";
  uint8_t laenge = strlen(t3) + strlen(t1) + strlen(t4) + strlen(t2) + 4;
  char buf[laenge];
  snprintf( buf, sizeof(buf), "%s%s%s%s", t3, t1, t4, t2 );
  Serial.println(buf);
}

void loop() {}

Wo kommen denn Temp1 und Temp2 her?
Ist deren Länge nicht in der aufrufenden Funktion bekannt?

[edit] @agmue war nen ticken schneller und macht das mit globalen udn deren Länge. Kommt schlußendlich aufs Gleiche raus.[/edit]

Das muß nicht, geht auch lokal:

void setup()
{
  char text1[20] = {"Start"};
  char text2[] = {"Ende"};
  Serial.begin(9600);
  Serial.println(F("\nStart"));
  ausgabe(text1, text2);
  strcpy(text1, "Neuer Start");
  ausgabe(text1, text2);
}

void ausgabe(char* t1, char* t2)
{
  const char t3[] = "Text ";
  const char t4[] = " Text ";
  uint8_t laenge = strlen(t3) + strlen(t1) + strlen(t4) + strlen(t2) + 1;
  char buf[laenge];
  snprintf( buf, sizeof(buf), "%s%s%s%s", t3, t1, t4, t2 );
  Serial.println(buf);
}

void loop() {}

Beim Funktionsaufruf geht die Länge verloren, weshalb sizeof(t1) nicht funktioniert. Bei einer Zeichenkette kann das mit strlen(t1) aufgefangen werden.


EDIT: " + 4" geändert in " + 1", weil '\0` nur einmal gebraucht wird.

Hallo,
nein, die Länge ist nicht bekannt. Ich steuere damit WLED über meine Haussteuerung.
Der Temp1 ist der Lampenname und Temp2 der Befehl. Und dieser kann sehr lange werden...

Ann alle:
Danke für Eure Unterstützung.
Meine Lösung sieht jetzt so aus und funktioniert.

WLED(char* Name, char* Befehl){
    String a = Name;
    String b = Befehl;
    String Seitenaufruf;
    Seitenaufruf.reserve(200);
    Seitenaufruf = "http://wled-";
    Seitenaufruf += a;
    Seitenaufruf += "/win&";
    Seitenaufruf += b;
.....

Vermute zwar, dass es da wesentlich elegantere Wege gibt, die Ihr zum Teil auch beschrieben habt, aber so klappt es einwandfrei :wink:

Danke und Gruß
Ingo

Warum nicht?
Wenn ich aus setup()

aufrufe, dann kann ich doch mit dem Aufruf auch die Größe mit übergeben.

ausgabe(text1, text2, sizeof(text1), sizeof(text2));

und baue dann in ausgabe wieder alles zusammen:

void ausgabe(char* t1, char* t2, uint8_t &lent1, uint8_t &lent2)
{
  const char t3[] = "Text ";
  const char t4[] = " Text ";
  uint16_t laenge = lent1 + lent2 +sizeof(t3)+sizeof(t4);
  char buf[laenge];
  snprintf( buf, sizeof(buf), "%s%s%s%s", t3, t1, t4, t2 );
  Serial.println(buf);
}

Oder?

Warum übergibst Du die beiden uit8_t als Referenz?
Evtl. char buf[laenge+1]; ?

Gruß Tommy

War blos nen Geschreibsel :wink: da hätte noch'n const vor gemußt.
Ich bin grad am rechnen...
text1 ist auf 20 incl. \0 festgelegt. Das Ende wird durch das erste aufkommen von \0 gesetzt.
text2 ist 5 (4+\0)
t3 ist 5 + und t4 6 +.
Macht in Summe: 19+4+5+6+\0 = 35 die ich brauche.
size of gibt mir doch die länge incl. \0 zurück.
Damit bekomme ich 20+5+6+7 = 38
Theoretisch könnte ich für die bufferlänge sogar bei jedem sizeof() 1 abziehen und zum bauen genau nur einmal 1 wieder dazu addieren.
:question:

(task: Controller in die Tasche stecken für Codeschnipsel unterwegs testen)

Solcherart dynamischer Arrays auf dem Stack sind nicht ISO C++ Standard kompatibel.
Mit "pedantic" schimpft der Compiler dann.
Auch ist der Stack, z.B. bei FreeRTOS begrenzt, was dann zu Problemen führen kann.

Es ist also irgendwie ok das zu tun, nur nicht unter allen Umständen.

Da gebe ich Dir Recht. Aber nochmal: Warum die uint8_t als Reference? Die werden ja nicht verändert.

Gruß Tommy

Die hat da nix zu suchen. Da sind zwei nicht zusammengehörende Geschreibsel vermengt worden. Man sehe es mir nach.

Da mußt Du die Macher von C++ fragen :innocent:

Ja, weil bei der Übergabe eines Zeigers an eine Funktion die Information über die Länge des Feldes verloren geht. Zusammen mit dem Zeiger sollte man also auch die Länge des Feldes (der Struktur, des Objektes ...) mit übergeben. Eigentlich.

Da Zeichenketten mit '\0' abgeschlossen sind, kann man in diesem Fall aber auf eine Längenangabe verzichten. Das macht den Ausgabepuffer buf sogar kleiner:

// https://forum.arduino.cc/t/strings-oder-chars-unbestimmter-lange-zusammenfugen/1072521/5
// Strings oder Chars unbestimmter Länge zusammenfügen
void setup()
{
  Serial.begin(9600);
  Serial.println(F("\nStart"));
  char text1[20] = {"Start"};
  char text2[] = {"Ende"};
  char puffer[70];
  snprintf( puffer, sizeof(puffer), "in setup    Länge text1: %2u  Länge text2: %2u", sizeof(text1), sizeof(text2) );
  Serial.println(puffer);
  ausgabe1(text1, text2);
  ausgabe2(text1, sizeof(text1), text2, sizeof(text2));
  strcpy(text1, "Neuer Start");
  ausgabe1(text1, text2);
  ausgabe2(text1, sizeof(text1), text2, sizeof(text2));
}

void ausgabe1(char* t1, char* t2)
{
  const char t3[] = "Text ";
  const char t4[] = " Text ";
  char puffer[70];
  snprintf( puffer, sizeof(puffer), "in Funktion    Länge t1: %2u  Länge t2: %2u <- stimmt nicht!", sizeof(t1), sizeof(t2) );
  Serial.println(puffer);
  uint8_t laenge = strlen(t3) + strlen(t1) + strlen(t4) + strlen(t2) + 1;
  char buf[laenge];
  snprintf( buf, sizeof(buf), "%s%s%s%s", t3, t1, t4, t2 );
  Serial.print(buf);
  snprintf( puffer, sizeof(puffer), "  buf-Länge: %2u", laenge );
  Serial.println(puffer);
}

void ausgabe2(char* t1, uint8_t l1, char* t2, uint8_t l2)
{
  const char t3[] = "Text ";
  const char t4[] = " Text ";
  char puffer[70];
  snprintf( puffer, sizeof(puffer), "in Funktion    Länge t1: %2u  Länge t2: %2u <- stimmt!", l1, l2 );
  Serial.println(puffer);
  uint8_t laenge = strlen(t3) + l1 + strlen(t4) + l2 + 1;
  char buf[laenge];
  snprintf( buf, sizeof(buf), "%s%s%s%s", t3, t1, t4, t2 );
  Serial.print(buf);
  snprintf( puffer, sizeof(puffer), "  buf-Länge: %2u <- zu lang!", laenge );
  Serial.println(puffer);
}

void loop() {}

Serieller Monitor, per Hand nachformatiert:

Start
in setup    Länge text1: 20  Länge text2:  5

in Funktion    Länge t1:  2  Länge t2:  2 <- stimmt nicht!
Text Start Text Ende        buf-Länge: 21
in Funktion    Länge t1: 20  Länge t2:  5 <- stimmt!
Text Start Text Ende        buf-Länge: 37 <- zu lang!

in Funktion    Länge t1:  2  Länge t2:  2 <- stimmt nicht!
Text Neuer Start Text Ende  buf-Länge: 27
in Funktion    Länge t1: 20  Länge t2:  5 <- stimmt!
Text Neuer Start Text Ende  buf-Länge: 37 <- zu lang!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.