Forum: Mikrocontroller und Digitale Elektronik C Frage zu Array Initialisierung mit Festtext


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Thorsten S. (whitejack)


Lesenswert?

geht das noch einfacher?

const char  mjanuar[] = "Januar\n";
const char  mfebruar[] = "Februar\n";
const char  mmaerz[] =  "Maerz\n";
const char  mapril[] =  "April\n";

const char * Text1[4]={mjanuar,mfebruar,mmaerz,mapril};

Ich möchte in Abhängigkeit einer Integer Variablen den Text mit einem 
Printf ausgeben...

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Thorsten S. schrieb:
> geht das noch einfacher?

Nicht wirklich.

Wo ist dein Problem?


Ist zwar Arduino C++, aber vielleicht kannste dir ja was abschauen.
1
#include <Streaming.h> // die Lib findest du selber ;-)
2
3
const char * Text2[]={"Januar","Februar","Maerz","April"};
4
5
6
void ausgabe(unsigned index, const char ** strField, Print &p)
7
{
8
  char buffer[20];
9
  sprintf(buffer,"Monat %s", strField[index]);
10
  p << buffer << endl;
11
}
12
void setup() 
13
{
14
  Serial.begin(9600);
15
  Serial << "Start: " << __FILE__ << endl;
16
17
  ausgabe(0,Text2,Serial);
18
  ausgabe(1,Text2,Serial);
19
  ausgabe(2,Text2,Serial);
20
}
21
22
void loop() 
23
{
24
25
}

: Bearbeitet durch User
von Thorsten S. (whitejack)


Lesenswert?

Arduino F. schrieb:
> Wo ist dein Problem?

Mir fehlte etwas die Notation dafür.

Ich hatte es irgendwie so versucht:

const char Text[3]={{"Januar\n"},{"Februar\n"},{"Maerz\n"}};

Dann so:

const char Text[]={{"Januar\n"},{"Februar\n"},{"Maerz\n"}};

Dann so meine ich...

const char * Text[3]={"Januar\n","Februar\n","Maerz\n"};

Danke. Ich war mir nicht sicher, wie das am besten gehen kann, was 
möglich ist, auch da die Zeichenketten unterschiedliche Längen haben... 
Irgendwann dachte ich, es ist besser es mit einem Array von Pointern auf 
Zeichenketten zu versuchen, das o.g. Beispiel funktioniert ja auch, nur 
war meine Hoffnung das sich das noch vereinfachen lässt für die 
Initialisierung, und das ist ja der Fall - perfekt!

Gruß

: Bearbeitet durch User
von Thorsten S. (whitejack)


Lesenswert?

Am Rande noch,

ich habe auch noch den Fall:


typedef struct
{
   uint8_t a :5,
           b :3;

}sub_t;


typedef struct
{
   uint8_t x;
   uint8_t y;
   sub_t   z[20];
}main_t;


main_t test; //Init?

bekomme ich das komplett auf allen Ebenen bei der Deklaration mit Nullen 
gefüllt, ähnlich wie hier:

uint8_t test1[2]={0,0};


und, wenn - dann wie? Ansonsten bleibt ja nur eine Schleife bei der 
Initialsierung, oder?

Oder ich mache ein Feld das genauso groß ist wie main_t, füttere das mit 
Nullen und mache einen Typecast, aber auch sehr unschön, zumal das 
sicher unter gewissen Umständen auch gut schief gehen kann...

Danke

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Thorsten S. schrieb:
> auch da die Zeichenketten unterschiedliche Längen haben...

Thorsten S. schrieb:
> Ich hatte es irgendwie so versucht:
Versuchen, ist eigentlich die falsche Strategie.
Ein C Grundlagenbuch auswendig zu lernen, ist deutlich 
erfolgversprechender.

Ich durfte das vor Jahrzehnten mal tun, und die Früchte dessen kann ich 
auch Heute noch ernten. Selbst wenn ich mittlerweile fast ausschließlich 
auf dem C++ Schiffchen fahre.

von Falk S. (falk_s831)


Lesenswert?

Thorsten S. schrieb:
> bekomme ich das komplett auf allen Ebenen bei der Deklaration mit Nullen
> gefüllt, ähnlich wie hier:
>
> uint8_t test1[2]={0,0};
>
>
> und, wenn - dann wie? Ansonsten bleibt ja nur eine Schleife bei der
> Initialsierung, oder?

Sollte mit einem memset(&test, 0, sizeof(test)) machbar sein.

Allerdings würde ich dir perspektivisch empfehlen, die C++-Notationen zu 
nutzen, anstatt das gute alte Herumgepointere. Arduino mag zwar 
eingeschränkt sein, was die Container betrifft auf den kleinen 
Controllern, aber sowas hier sollte auch als C++-Strukturdefinition 
gehen, glaube ich, zumindest ab C++20:
1
struct sub_t
2
{
3
   uint8_t a : 5 = 0;
4
   uint8_t b : 3 = 0;
5
};

Kann sein, dass du dafür -std=c++20 mitgeben musst.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Thorsten S. schrieb:
> Dann so meine ich...
> const char * Text[3]={"Januar\n","Februar\n","Maerz\n"};

Nur ein Tipp: Lass die \n raus aus den Zeichenketten und packe nur eines 
in Dein printf(). Damit bist Du flexibler.

von Thorsten S. (whitejack)


Lesenswert?

Frank M. schrieb:
> packe nur eines
> in Dein printf()

jup, stimmt, guter Tip

von Peter D. (peda)


Lesenswert?

Der avr-gcc ist da recht unflexibel. Das direkte Anlegen eines Arrays 
von Strings geht nur im RAM.
Im Flash muß man dazu ein zweidimensionales Array anlegen, d.h. alle 
Strings mit der maximal benötigten Länge. Das ist typisch aber kein 
Problem, da Flash ja reichlich vorhanden ist.

Hier mal ein Beispiel aus meinem Kommandoparser:
1
#define CMD_SIZE        16
2
3
typedef char cmd_str_t[CMD_SIZE];
4
5
typedef void (*func)(void);
6
7
typedef struct
8
{
9
  cmd_str_t cmd;
10
  cmd_str_t cmd_short;
11
  func func;
12
} command_t;
13
14
extern command_t const cmd_table[] PROGMEM;
15
16
command_t const cmd_table[] PROGMEM =
17
{
18
  {MODULE_CMD_INFO,          "i",   cmd_info},
19
  {MODULE_CMD_SERIALNO,      "sn",  cmd_serno},
20
  {MODULE_CMD_RESET,         "re",  cmd_reset},
21
  {MODULE_CMD_EECLEAR,       "epc", cmd_eeclear},
22
  {"", "", 0},
23
};
Die Zugriffe müssen auch abweichend vom Datasegment mit den 
Spezialfunktionen erfolgen (pgm_read_byte, pgm_read_word, strcmp_P 
usw.).


Der Keil C51 kann das deutlich besser. Da ist es kein Unterschied, ob 
RAM oder Flash. Das entsprechende Schlüsselwort "code", "xdata" usw. 
reicht für alles, was nicht im default Datasegment liegt.

von Bruno V. (bruno_v)


Lesenswert?

Thorsten S. schrieb:
> Dann so meine ich...
>
> const char * Text[3]={"Januar\n","Februar\n","Maerz\n"};

Das sollte gegangen sein.

Eine Zeichenkette ("Hallo") ist eigentlich nur ein const Pointer. Bei 
Dir also eine Liste von 3 Pointern. Lediglich bei

char myString[]="Hallo";

wird das Array myString mit den Buchstaben von "Hallo" plus 
abschließender 0 initialisiert. Das ist eine Sonderbehandlung, eine 
Vereinfachung zu

char myString[]={'H','a','l','l','o',0};

Darum geht auch {"Hallo"} nicht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.