Strings an Array in Funktion übergeben

Hallo Leute,

leider finde ich in Google nichts darüber also versuche ich es hier:

Ich möche 4 Strings an eine Funktion übergeben. Soweit alles klar. Allerdings möchte ich nicht 4 Variablen im Funktionskopf deklarieren, sondern ein Array of Strings. Hier der Code:

Funktion("string0", "string1", "string2", "string3");

void Funktion(String Array[4])
{
Code;
}

wenn ich 4 Variablen im Funktionskopf verwende geht's problemlos. Aber wie deklariere ich ein Array im Funktionskopf, sodass string0 in das Array Index 0, string1 in das Array Index 1 usw geschrieben wird. Mit Pointer habe ich es auch nicht geschafft.

So Sachen wie

void Funktion(String string0, string1, string2, string3)
{
String Array[4];
Array[0] = string0:
Array[1] = string1;
...
}

sind mir klar, will ich mir aber wenns geht ersparen.

Vielleicht weiß das jemand von euch.

LG und danke

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

gibt es einen Grund, warum Du Strings verwenden musst?

wie suchst du denn?
Einer von den 908000 Ergebnissen wird doch passen.

aber wie schon angesprochen, was soll es den werden und warum müssen es String Objekte sein?

Wenn es denn unbedingt sein muss, kannst Du es so machen:

void printIt(String **str, int len) {
  for (byte i = 0; i < len; ++i) {
    Serial.println(*str[i]);
  }
}
 
void setup() {
  Serial.begin(115200);
  String string0  = "Das ist String0";
  String string1  = "Das ist String1";
  String string2  = "Das ist String2";
  String string3  = "Das ist String3";
  String string4  = "Das ist String4";
 
  String *stringArray[] {&string0, &string1, &string2, &string3, &string4};
  printIt(stringArray, sizeof(stringArray)/2);
}
 
void loop() {}

Habt ihr denn alle kein "Handbuch"?
:japanese_ogre: :japanese_ogre: :japanese_ogre: :japanese_ogre:

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





template<size_t N> void Funktion(String (&strings)[N])
{
  cout << F("Es wurde ein Array mit ") << N << F(" Strings uebergeben") << endl;
  for(String &s:strings) cout << s << endl;
}

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

  String strings[] {"string0", "string1", "string2", "string3"};
  Funktion(strings); // ok
  Funktion<4>(strings); // ok

  String stringsa[] {"stringa0", "stringa1", "stringa2", "stringa3", "stringa4"};
  Funktion(stringsa); // ok
  Funktion<4>(stringsa); // error
}

void loop() 
{

}

Wo ist das Problem bei einem Array von String - Objekten?

String s[4];
constexpr size_t len = sizeof(s)/sizeof(s[0]); // 4

void setup() {
 s[0] =  "String1 ";
 s[1] =  "String2 ";
 s[2] =  "String3 ";
 s[3] =  "String4 ";
  Serial.begin(115200);
  printSarray(s, len);
}

void printSarray( String strings[], size_t count) {
   for (int i = 0; i < count; i++) {Serial.print(strings[i]); if (i < count-1) Serial.print(" - "); }
   Serial.println();
} 

Bleibt natürlich die Frage, ob Strings sinnvoll sind.

Ich wollte mir dir globale Deklaration sparen, habe es aber, da das die sinnvollste Antwort hier ist, so ähnlich gemacht.

Meinem Array werden nicht nur Texte zugewiesen, sondern auch Variablen (bytes, floats, ...) und mit char() kann ich die in Kombination mit strcpy() oder strcat() nicht konvertieren.

String stringText[4];

stringText[0] = "Text 1";
stringText[1] = "Text 2";
stringText[2] = "Text 3";
stringText[3] = "Text 3 ";

void Funktion(void
{
for (byte i = 0; i <= 3; i++)
{
Serial.print(stringText[i];
}
}

Gefällt mir nicht, werde ich vielleicht noch umändern, aber ist zumindest für jetzt eine halbwegs brauchbare Lösung.

Vielleicht willst du gar kein Array haben, kennst nur nichts anderes?

Merke: in einem Array haben alle Elemente den gleichen Datentyp.
Merke: String ist ein Datentyp mit vielen Nachteilen.

Etwas, das verschiedene Datentypen vereint, ist eine struct oder class.
Das "etwas" nennt man dann auch Objekt und das ganze objektorientierte Programmierung OOP.

Da bist du nicht allein.

Doch doch ich will schon ein Array haben.
Ich habe einen 20x04 LCD Display. Also dachte ich, ein String[4] oder ein zweidimensionales char Array [20][4] bietet sich da an.

Mit Strings funktionierts nicht schlecht, ich kann mit String() meine floats usw problemlos konvertieren und ausgeben.

Ich hab das Programm eben etwas geändert

void Funktion(String s0, String s1, String s2, String s3)
{
String Text[4] = {s0, s1, s2, s3};

for (byte i = 0; i <= 3; i++)
{
LCD.setCursor(2, i);
LCD.print(Text[i]);
}
}

Beim Funktionsaufruf kann ich dann, weil ich es eben brauche, ifs, Konvertierungen usw. verwenden.

Vielleicht ändere ich das noch ein bisschen ab, aber da ich, wie gesagt, verschiedene Datentypen am LCD ausgeben muss, komme ich noch auf keine schönere Lösung.

Geht genauso auch mit einem lokalen String Array .

Strings haben die Eigenheit, dass der Text selber irgendwo anders gespeichert ist und seine Größe
ändern kann, was du gar nicht brauchst.

Schon klar

Auch klar, aber mit einem char-Array komme ich auch nicht weiter

Auch klar, ich habe schon so einige Programme geschrieben, Objekte erstellt, Bibliotheken geschrieben, ...

Ich habe durchaus Erfahrung mit logischen Abläufen, nur Strings und char brauche ich in meinen Anwendungen nicht so oft. Und der C-Kurs ist auch schon ein Jahr her

Der hilft sowieso kaum!
Du bist C++

In C gibt es keine Strings, nur char arrays. :slight_smile:

Ok dann Frage ich mal direkt(er):

Wenn ich eine float und einen Text in ein char-Array schreiben will, wie genau mache ich das?
Bzw wie hänge ich die float an das Array an (Stichwort strcat)?

hoppla :sweat_smile:

Ihm hat recht, in C gibts kein String.
Der allgemein so genannte C-String ist ein Array of char.
Mit der Konvention, nicht Spracheigenschaft, der \0 am Ende

Je nach Arduino ist sprintf oder dtostrf das was du suchst.
Ausserdem hängst du nichts irgendwo hinten an, sondern füllst es an einer bestimmten Stelle ein.

Und hoffst, nicht übers Ende hinaus zu rutschen
:slight_smile:

du hängst den float in einen temporären Buffer und machst dann dein strcat in deinen Zielbuffer.
oder du nimmst die PString.h und streamst (print) dein Float direkt in den Zielbuffer.

Wie das alles zu deinem LCD passt ist mir noch nicht klar. Die meisten LCD libraries erben eh von print, da würde ich nicht umbedingt vorher einen buffer befüllen/konkatinieren sondern gleich auf das LCD schreiben.

Ideal!

Aber: Das ist offensichtlich nicht gewollt!
Denn wenn, wäre LCD schon im Eingangsposting genannt worden.

Ich auch, da möchte ich formatiert Daten ausgeben, die ich einer Funktion zur Anzeige übergebe, damit ich die Formatierung nicht an verschiedenen Programmstellen wiederholen muß. Ich verwende gerne snprintf (diese Beschreibung gefällt mit besser, könnte aber ggf. nicht stimmen).

#include <Wire.h>                   // needed for the I2C interface
#include <NoiascaLiquidCrystal.h>      // download library from https://werner.rothschopf.net/202009_arduino_liquid_crystal_intro.htm 
#include <NoiascaHW/lcd_PCF8574.h>     // include the proper IO interface

const byte cols = 20;                  // columns/characters per row
const byte rows = 4;                   // how many rows
const byte addr = 0x27;                // set the LCD address to 0x3F or 0x27

LiquidCrystal_PCF8574 lcd(Wire, addr, cols, rows);               // create lcd object - with support of special characters

uint16_t zaehler = 0;

void setup()
{
  Wire.begin();                        // start I2C library
  lcd.begin();                         // initialize the LCD
  lcd.backlight();                     // turn on backlight
}

void anzeige(const uint32_t sekunden, const uint16_t z, const char * text)
{
  char buf[cols + 1] = "\0";
  snprintf( buf, sizeof(buf), "Sekunden: %5lu", sekunden );
  lcd.setCursor(0, 0);
  lcd.print(buf);
  snprintf( buf, sizeof(buf), "Zähler:   %5u", z );
  lcd.setCursor(0, 1);
  lcd.print(buf);
  snprintf( buf, sizeof(buf), "%10s", text );
  lcd.setCursor(0, 2);
  lcd.print(buf);
}

void loop() {
  zaehler++;
  anzeige(millis() / 1000, zaehler, "Mal so");
  delay(1000);
  zaehler++;
  anzeige(millis() / 1000, zaehler, "Mal anders");
  delay(1000);
}

Möglicherweise suchst Du nach sowas.