Problem mit struct Kontruktur und Textübergabe (Default leer)

Hallo,

ohne Konstruktor funktioniert das, nur dann kann man keine Defaultwerte vorgeben.

struct t_setup
{
  byte pin;
  char text[21];

};

t_setup KOMBI[] = {
  {1, "Hallsen. HSQ1"},
  {2, "Hallsen. HSQ2"},
  {3, '\0'},
  {4, "Hallsen. HSQ4"},
};

const byte ANZAHL = sizeof(KOMBI) / sizeof(t_setup);

void setup()
{
  Serial.begin(9600);
  for (byte i=0; i<ANZAHL; i++) {
      Serial.println(KOMBI[i].pin);
      Serial.println(KOMBI[i].text);
  }
}

void loop()
{}

Mit Konstruktor bekomme ich es nicht hin. Habe auch Pointer und Adressübergabe probiert.
So sollte es werden. Was ist falsch?

//  funktioniert nicht

struct t_setup
{
  byte pin;
  char text[21];

  // Konstruktor
  t_setup (byte _pin) :
    pin(_pin),
    text('\0')
  {}  
};

t_setup KOMBI[] = {
  {1, "Hallsen. HSQ1"},
  {2, "Hallsen. HSQ2"},
  {3},
  {4, "Hallsen. HSQ4"},
};

const byte ANZAHL = sizeof(KOMBI) / sizeof(t_setup);


void setup()
{
  Serial.begin(9600);
  for (byte i=0; i<ANZAHL; i++) {
      Serial.println(KOMBI[i].pin);
      Serial.println(KOMBI[i].text);
  }
}

void loop()
{}

Dass man C Strings nicht zu einfach zuweisen kann solltest du inzwischen wissen. Dafür gibt es strcpy(), strncpy(), strlcpy() und ähnliches (z.B. die _P Varianten auf den AVRs)

struct t_setup {
  byte pin;
  char text[21];

  t_setup (byte _pin, const char* _data = nullptr) : pin(_pin) {
    if (_data != nullptr) {
      strncpy(text, _data, sizeof(text));
    } else {
      *text = 0;
    }
  }
} KOMBI[] = {
  {1, "Hallsen. HSQ1"},
  {2, "Hallsen. HSQ2"},
  {3},
  {4, "Hallsen. HSQ4"},
};

const byte ANZAHL = sizeof(KOMBI) / sizeof(t_setup);

void setup() {
  Serial.begin(250000);
  for (byte i = 0; i < ANZAHL; i++) {
    Serial.print(F("pin: "));
    Serial.print(KOMBI[i].pin);
    Serial.print(F(". text: \""));
    Serial.print(KOMBI[i].text);
    Serial.println(F("\""));
  }
}

void loop() {}
pin: 1. text: "Hallsen. HSQ1"
pin: 2. text: "Hallsen. HSQ2"
pin: 3. text: ""
pin: 4. text: "Hallsen. HSQ4"

Um auch überlange Strings korrekt zu übernehmen braucht es noch einen Hauch mehr.

struct t_setup {
  byte pin;
  char text[21];

  t_setup (byte _pin, const char* _data = nullptr) : pin(_pin) {
    if (_data != nullptr) {
      strncpy(text, _data, sizeof(text));
      text[sizeof(text) - 1] = 0;
    } else {
      *text = 0;
    }
  }
} KOMBI[] = {
  {1, "Hallsen. HSQ1 12345678901234567890"},
  {2, "Hallsen. HSQ2"},
  {3},
  {4, "Hallsen. HSQ4"},
};

const byte ANZAHL = sizeof(KOMBI) / sizeof(t_setup);

void setup() {
  Serial.begin(250000);
  for (byte i = 0; i < ANZAHL; i++) {
    Serial.print(F("pin: "));
    Serial.print(KOMBI[i].pin);
    Serial.print(F(". text: \""));
    Serial.print(KOMBI[i].text);
    Serial.println(F("\""));
  }
}

void loop() {}
pin: 1. text: "Hallsen. HSQ1 123456"
pin: 2. text: "Hallsen. HSQ2"
pin: 3. text: ""
pin: 4. text: "Hallsen. HSQ4"

Dafür wurde strclpy() erfunden:

https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__string_1ga64bc119cf084d1ecfd95098994597f12.html

At most siz-1 characters will be copied. Always NULL terminates

Serenifly:
Dafür wurde strclpy() erfunden:

Die AVR Dokumentation ist zwar sehr dürftig, aber es gibt sogar strlcpy_P().

const char hsq1Name[] PROGMEM = "Hallsen. HSQ1 12345678901234567890";
const char hsq2Name[] PROGMEM = "Hallsen. HSQ2";
const char hsq4Name[] PROGMEM = "Hallsen. HSQ4";

struct t_setup {
  byte pin;
  char text[21];

  t_setup (byte _pin, const char* _data = nullptr) : pin(_pin) {
    if (_data != nullptr) {
      strlcpy_P(text, _data, sizeof(text));
    } else {
      *text = 0;
    }
  }
} KOMBI[] = {
  {1, hsq1Name},
  {2, hsq2Name},
  {3},
  {4, hsq4Name},
};

const byte ANZAHL = sizeof(KOMBI) / sizeof(t_setup);

void setup() {
  Serial.begin(250000);
  for (byte i = 0; i < ANZAHL; i++) {
    Serial.print(F("pin: "));
    Serial.print(KOMBI[i].pin);
    Serial.print(F(". text: \""));
    Serial.print(KOMBI[i].text);
    Serial.println(F("\""));
  }
}

void loop() {}
pin: 1. text: "Hallsen. HSQ1 123456"
pin: 2. text: "Hallsen. HSQ2"
pin: 3. text: ""
pin: 4. text: "Hallsen. HSQ4"

Hallo,

naja zuweisen geht schon einfach. Wie im ersten Sketch oder ganz simpel

char text[21] = {"TEXT"};

und text ausgeben.

Ich dachte ich mach im Konstruktor mit Pointer oder Adressübergabe etwas falsch.
Das es nun so kompliziert wird hätte ich nicht gedacht.
Das man für die "Initialisierung" noch Kopierfunktionen benötigt.
Vielen Dank. ** Das ist richtig cool. :)**

naja zuweisen geht schon einfach. Wie im ersten Sketch oder ganz simpel

Das sieht nur aus, wie eine Zuweisung, ist aber keine.
Es ist eine Initialisierung.

Beweis:

char text1[21] = {"TEXT"};
char text2[21] {"TEXT"};

Bei einer Zuweisung könnte man den = Operator nicht weg lassen.

Stimmt ist eine Initialisierung. :confused: