String zusammensetzen

Hi,

ich komme auch nach langem Suchen leider nicht weiter mit einem Problem.
Dazu muss ich sagen, dass ich vor vielen Jahren mit anderen Programmiersprachen gecoded habe, und mir das möglicherweise auch ein wenig im Wege steht.

Für folgenden Aufruf:

if (sendRequest(server, resource) && skipResponseHeaders()) {  .......und so weiter

benötige ich den String "resource", in dem eine Adresse/Datei steht:

const char* resource = "/middleware.php/channel/05ce3300-87c7-12e6-acf4-75126546683c.json";

Nun möchte ich aber nicht nur eine Adresse aufrufen, sondern 7 verschiedene.
(Später sollen die gleichen 7 Adressen auch noch auf einen anderen Pfad und mit weiteren Parametern aufgerufen werden)
Damit man nun nicht jede einzelne Adresse als Variable hinterlegen muss, möchte ich diese aus den Einzelteilen zusammensetzen.

Dazu habe ich mir die Einzelteile bereits hinterlegt:

const char* channelfolder = "/middleware.php/channel/";
const char* channelextension = ".json";

char *UUID[7] = { 
"05ce3300-87c7-12e6-acf4-75126546683c",
"18975470-87e4-12e6-a22a-6142657676b4",
"b64be560-8915-12e6-84ac-37363467454e",
"e7345f60-8898-12e6-b7f6-7df7687657b3",
"d08a8370-87e3-12e6-bb10-e9634634682b",
"4b321940-87e4-12e6-8968-98896747784a",
"60b75840-87d9-12e6-8c9e-e75647887c3f"
};

Nun fehlt nur noch die Zusammensetzung zu einem String "resource", damit der Aufruf wieder funktioniert.
Sinngemäß für die erste Kombination:
resource = channelfolder + UUID[0] + channelextension

Wie macht man das richtig?

Danke und lieben Gruß,
Chris

Was willst Du denn sparen? Flash, RAM, Wartungsaufwand, Rechenkapazität?

RAM kannst du mit PROGMEM sparen, Wartungsaufwand könntest Du mit precompiler statements lösen:

#DEFINE CHANNELFOLDER "middleware.php/channel/"

const char channel [] PROGMEM = CHANNELFOLDER "05ce3300-87c7-12e6-acf4-75126546683c";

Der Precompiler ersetzt nicht nur CHANNELFOLDER, sondern fügt auch die Strings zusammen.

Ansonsten musst Du halt strcat nehmen, dafür brauchst aber eine lokale Puffervariable, die so groß ist wie der gesamte String.

Moin,

Den Wartungsaufwand möchte ich sparen.
Die Pfade und UUIDs sind bei jedem, der das Programm benutzen will anders.
Damit das Programm übersichtlicher und einfacher zu pflegen ist, sollen die aus den Einzelteilen zusammengesetzt werden.
Außerdem will ich die Funktionen mit Variablen steuern.

Inzwischen habe ich doch was gefunden, so müsste das doch funktionieren, oder?

char resource[128]="";   // String mit maximal 128 Zeichen
int pos = 2;
strcpy(resource,channelfolder);
strcat(resource,UUID[pos]);
strcat(resource,channelextension);

Danke und lieben Gruß,
Chris

Wenn es sich bei deinen Strings um Konstanten handelt, benutze strcpy_P, strcat_P, ...

Whandall:
Wenn es sich bei deinen Strings um Konstanten handelt, benutze strcpy_P, strcat_P, …

Nur so aus Interesse, was ist der Unterschied (unter der Haube)? SRAM ja anscheinend nicht, man bracuht ja immer noch ein Pufferarray.

themanfrommoon:
Den Wartungsaufwand möchte ich sparen.
Die Pfade und UUIDs sind bei jedem, der das Programm benutzen will anders.
Damit das Programm übersichtlicher und einfacher zu pflegen ist, sollen die aus den Einzelteilen zusammengesetzt werden.
Außerdem will ich die Funktionen mit Variablen steuern.

In meinen IoT Sachen mit ESP8266s inkludiere ich immer eine Headerdatei mit sowas. Ich habe mich für die MQTT-Pfade für die Precompilervariante entschieden, weil das eben keinen Buffer braucht und in einer Zeile erledigt ist.
Hat auch den Vorteil, dass man das Projekt unverändert auf Github schmeißen kann, ohne seine Passwörter usw. hochzuladen. (Headerdatei ignorieren und als .h.example mit Dummywerten hochladen.)

ElCaron:
Nur so aus Interesse, was ist der Unterschied (unter der Haube)? SRAM ja anscheinend nicht, man bracuht ja immer noch ein Pufferarray.

Der kopierte/angehängte Text steht bei den Funktionen (nur) im Flash (PROGMEM).

Whandall:
Der kopierte/angehängte Text steht bei den Funktionen (nur) im Flash (PROGMEM).

Aber man belegt doch schon mit dem Puffer dest den gesamten Speicher?
Wo spart man da was?

Bei source?

String Literale werden normalerweise ins RAM kopiert! Weil die normalen Assembler-Befehle nur mit Daten im RAM umgehen können

Whandall:
Bei source?

Serenifly:
String Literale werden normalerweise ins RAM kopiert! Weil die normalen Assembler-Befehle nur mit Daten im RAM umgehen können

Ah, ok. :slight_smile:

Was willst du damit ausdrücken?

Glaubst du pgm_read_byte() sei eine normale Instruktion?

Nein, das war ein reines, unironisches "Ah, das klingt sinnvoll, verstanden". Das :slight_smile: sieht aber auch sehr nach einem :smiley: aus ...