Inhalt einer const char anhand eines ASCII "-" in 2 Teile (char) aufteilen

Hallo,
ich habe einen kleinen StreamServer am laufen.
Dieser gibt unter anderem unter einer const char
den Interpret und den Song aus.

const char *Info;

Der Inhalt dieser sieht wie folgt aus:
Als Beispiel:
Interpret - lalalalalala

Nun ist es so, das auf einem I2C TFT leider kein Platz für alle diese Infos ist.
Auch scrollen ist keine Lösung.
Ein Überlauf auf dem TFT in die nächste Zeile sieht auch unsauber aus.

Nun zu der Frage:
Gibt es eine Möglichkeit die const char*Info, bzw. den Inhlat dieser irgendwie in 2 Char aufzuteilen und zwar nach einerRegel die besagt.

  • alles vor dem "-" = erste Char
  • alles nach dem "-" = zweite Char

Somit wäre das "-" welches immer vorhanden ist der "Teiler"
und ich könnte die Info im I2C Display sauber und definiert in 2 Zeilen bringen.

Eine Idee oder Ansatz wäre klasse.
Schöne Grüße....

Mit const nicht wirklich sinnvoll, da solltest Du besser beide Teile in getrennten Variablen halten. Die verändern sich ja nicht (const).
Bei veränderbaren Zeichenketten (char-Array) könnte strtok(...) für Dich nützlich sein.

Gruß Tommy

Hallo Tommy,
vielen Dank , das Stichwort "strtok" ist super.
Damit probiere ich mal los :slight_smile:
Grüße Rainer

Oder strstr()

@rainerkol
Es gibt übrigens sowas wie eine Doku.
https://www.nongnu.org/avr-libc/user-manual/group__avr__string.html

Jeder mag eine andere Doku: Split string into tokens :slightly_smiling_face:

Das mag sein!

Es nur so, dass zumindest die AVR #include <cstring> von hause aus nicht können.
Aber dafür #include <string.h> schon per default eingebunden wird.

Damit könnte es ..........
Wie auch immer: Freie Auswahl!

#include <Streaming.h> // die Lib findest du selber ;-)
Print &cout = Serial; // cout Emulation für "Arme"

char nadel[]     {" - "};
char heuhaufen[] {"Interpret - lalalalalala"};

void setup() 
{
  Serial.begin(9600);
  cout << F("Start: ") << F(__FILE__) << endl;

  char *vorn, *hinten, *fundstelle;

  if((fundstelle=strstr(heuhaufen,nadel)))
  {
    vorn = heuhaufen;
    fundstelle[0] = 0;
    hinten = fundstelle + strlen(nadel);
    cout << vorn << " -X- " << hinten << endl;
  }
}

void loop() 
{

}
fundstelle[0] = 0;

geht aber nur bei einem nicht konstanten char-Array. Der TO wollte aber ein konstantes teilen.

Gruß Tommy

Da hast du vollkommen Wahr!

Dafür gilt das aber genau so.

Dann haben wir eben beide versagt.
z.B. ich völlig und du nur ein bisschen.
:upside_down_face:

Wenn ich mich richtig erinnere, könnte ich mich mit memcpy() noch aus der Affäre ziehen und strstr() weiter verwenden. Mit strtok() wird das schon schwieriger, oder man muss den ganzen String kopieren.

Wenn man es zur Laufzeit aufteilen will, darf der Text nicht const sein, oder muss mindestens in zwei nicht const Texte umkopiert werden.
Da ist es gut, wenn der Text schon von vornherein nicht const wäre oder schon immer in zwei Teilen vorliegen würde, wie @Tommy56 bereits am Anfang von #2 vorschlug.

Gibt aber auch eine Lösung mit const char*

const char nadel[]     {" - "};
const char heuhaufen[] {"Interpret - lalalalalala"};

void setup() 
{
  Serial.begin(9600);

  const char *vorn, *hinten, *fundstelle;

  if((fundstelle=strstr(heuhaufen,nadel)))
  { 
    vorn = heuhaufen;
    hinten = fundstelle + strlen(nadel);
    Serial.write (vorn, fundstelle-vorn);    // Anfang , Länge  !
    Serial.write ( " === ");
    Serial.println (hinten);
  }
}

Wenn der Trenner nur das '-' Zeichen, statt des ganzen Textes " - " ist, gehts gar noch einen Tick einfacher.

Nur einen Buffer, für das vordere Ende, man braucht.
Für das hintere Zipfelchen reicht ein "verbogener" Pointer.

Wenn man keine Scheu vorm kopieren hat, dann evtl.:

#include <Streaming.h> // die Lib findest du selber ;-)
Print &cout = Serial; // cout Emulation für "Arme"

class MyString : public String
{
  private:
  using String::String;
  char *nedle;  
  
  public:
  using String::operator=;
  explicit MyString(const char *haystack, const char *nedle):String{haystack},nedle{nedle} {}
  String anfang(){return  substring(0,indexOf(nedle));}
  String ende()  {return  substring(indexOf(nedle)+strlen(nedle));}
};


const char nadel[]     {" - "};
const char heuhaufen[] {"Interpret - lalalalalala"};

void setup() 
{
  Serial.begin(9600);
  cout << F("Start: ") << F(__FILE__) << endl;

  MyString my {heuhaufen,nadel};
  cout << my.anfang() << " -X- "  << my.ende() << endl;
  
  my = "Vorn - Hinten"; 
  cout << my.anfang() << " -X- " << my.ende() << endl;
}

void loop() 
{

}

Du möchtest mir sagen, avr-libc <string.h> unterscheidet sich von <cstring> (string.h)?

Ich lerne schneller von Beispielen als von schwurbeligem Text und möchte gerne das verlinken, was ich auch selbst verstehe. Ach manno, ich möchte eine für mich verständliche Doku, die ich auch verlinken kann!

Deshalb hatte ich für const vorgeschlagen, gleich beide Teile in getrennte Variablen zu packen. Das wäre aber wohl zu einfach.

Gruß Tommy

Ja, das Libc <string.h> unterscheidet sich von Libstdc++ <cstring>.
Und wenn es auch nur der Punkt ist, dass bei dem einen, dem erstgenannten, alle Funktonen den globalen Namensraum fluten, aber die anderen im namespace std stecken.

hier mal die <cstring>, zumindest eine für AVR verfügbare:
(habe mal ein .h an den Namen gehangen, damit ich sie überhaupt hier hochladen kann)

cstring.h (3,1 KB)

Vergleichbares gilt auch für math.h und viele weitere.

Hallo Jungs , vielen lieben Dank für eure Tips.
Ich habe heute viel probiert, aber leider klappt es noch nicht.
Mit einem "char" und strtok habe ich es in einem unabhängigem Beispiel
einfach zum laufen bekommen.
Jedoch mit dem const Char *info klappt es nicht.

Ja, am einfachsten wäre ein einfaches Char, aber das bekomme ich leider nicht raus.
Die Lib des Stream gibt das leider so aus und ich bekomme es nicht geändert.

Ich werde weiter probieren, hab auch mal den Lib ersteller angeschrieben wie ich seine Variable als normale Char bekommen könnte.

Ich danke euch schonmal für die Erweiterung meines Horizontes. :slight_smile:

Wenn das aus einem Stream kommt wird das wohl kaum const sein.
Nun mach mal Butter bei die Fische, gib uns Links zu den Libs, Deinen Sketch und beschreibe, was das werden soll.

Das strtok mit const nicht geht, hatte ich Dir bereits in #2 geschrieben.

Gruß Tommy

Das strstr() auch mit const geht, hatte ich Dir bereits in #4 geschrieben.

Dabei habe ich doch mindestens 1 definitiv funktionierendes MyString Beispiel geliefert.
Hast du das übersehen?

Alles wurde genannt, alles vorgeschlagen, mehrere Dokus verlinkt.
Welche Probleme plagen dich, dass du es damit nicht hin bekommst?

HI, das keine Missverständnisse aufkommen.
Alles probiert, Dokus gelesen.
Funktinoiert alles wenn ich es ausprobiere als EInzeltestscript.
Nur mit der "Aufteilung" der const char* innerhalb der Audio lib geht es eben nicht.
Ich werde mal weiter probieren und mich Schrittweise annähern.

PS: Ja ich bereite euch mal die "lib"s usw" auf , aber erstmal will ich selber weng probieren.
Grüße und Danke euch für die Tips...

PS: Doch , doch die Stream lib macht einen const char*, und zwar durchgängig von der *.h bis *. cpp und bis zur *.ino.....

showstreamtitle(const char* ml) 
showstreaminfo(const char *info)

etc....als Beipiel davon

Last mich noch mal weng probieren, dann stelle ich euch nochmal mehr infos zusammen.

Grüße an euch :slight_smile:

Mir scheinst Du verwechselst

const char *
// mit
const char[]

Gruß Tommy

Und nochmal: Mein Beispiel kann das!

@rainerkol: Sorry wegen der parallelen Unterhaltung, aber meist lohnt sich bei @combie ein Nachhaken. Noch fehlt mir allerdings der AHA-Effekt :thinking:

Auf meiner Festplatte, ESP32 weggelassen, finde ich nur c:\Program Files (x86)\Arduino-1.8.19\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1\cstring mit etwas anderem Inhalt. Bei Dir steht zusätzlich extern "C++" drin. Aber ARM ist doch nicht AVR, oder?

Welche Erkenntnis sollte mir der Blick in die Datei denn bescheren?