Forum: Mikrocontroller und Digitale Elektronik Wie mache ich einen Zugriff auf Textarrays?


von Peter H. (Gast)


Lesenswert?

Hallo liebes Forum,
irgendwie bekomme ich das nicht richtig hin mit den Texten. Ich möchte 
mehrere Texte in einem 2D- Array schreiben und dies dann gegeben falls 
auslesen.
Vereinfacht sieht mein Programm so aus...


Im ersten Modul fülle ich das Array.
-------------------------------------------------------
unsigned char alle_texte[3];
unsigned char text_01[5] = „Peter“;
unsigned char text_02[5] = „Klaus“;
unsigned char text_03[3] = „Ute“;

void init_text_array(void)
{
  alle_texte[0] = &text_01;
  alle_texte[1] = &text_02;
  alle_texte[2] = &text_03;
}

// Funktion um das Array auszulesen
void get_text(unsigned char nr, unsigned char *text)
{
  text = alle_texte[nr];
}
-------------------------------------------------------

In einem zweiten Modul lese ich dann diese Arrays wieder aus.
-------------------------------------------------------
void print_lcd(void)
{
  unsigned char *ausgabe;
  …
  Get_text(1,ausgabe);
  …
}
-------------------------------------------------------

Ich bekomme das aber irgendwie nicht richtig hin. Hat jemand Ahnung was 
ich falsch mache?
Grüße, Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter H. schrieb:

> Im ersten Modul fülle ich das Array.
> -------------------------------------------------------
> unsigned char alle_texte[3];
> unsigned char text_01[5] = „Peter“;
> unsigned char text_02[5] = „Klaus“;
> unsigned char text_03[3] = „Ute“;
>
> void init_text_array(void)
> {
>   alle_texte[0] = &text_01;
>   alle_texte[1] = &text_02;
>   alle_texte[2] = &text_03;
> }

Das kann aber nicht stimmen. Denn text_01 (den & kannst du weglassen. 
Der Name eines Arrays steht automatisch für seine Adresse) ist eine 
Adresse. alle_texte kann aber keine Adressen speichern. alle_texte kann 
unsigned chars speichern. Die hast du aber nicht, du hast ja Adressen.

Also wird es wohl
1
unsigned char * alle_texte[3];
heissen müssen.


> // Funktion um das Array auszulesen
> void get_text(unsigned char nr, unsigned char *text)
> {
>   text = alle_texte[nr];
> }

Auch das kann nicht stimmen. wenn du das Ergebnis so nach aussen geben 
willst, dann musst du einen Pointer auf den Ergebnisdatentyp übergeben 
und der Aufrufer muss die Adresse einer Variablen angeben, die das 
Ergebnis erhalten soll. Im Falle eines int
1
void foo( int* i)
2
{
3
  *i = 5;
4
}
5
6
int main()
7
{
8
  int j;
9
  foo( &j );
10
}
oder im allgemeinen für einen Datentyp T dann eben
1
void foo( T* i)
2
{
3
  *i = Wert_für_T;
4
}
5
6
int main()
7
{
8
  T j;
9
  foo( &j );
10
}

bei dir ist T der Datentyp 'Pointer auf unsigned char'. Anstatt T also 
einen "unsigned char *" eingesetzt ergibt dann
1
void foo( unsigned char** i)
2
{
3
  *i = "hallo";
4
}
5
6
int main()
7
{
8
  unsigned char* j;
9
  foo( &j );
10
}
Bei dir dann eben
1
void get_text(unsigned char nr, unsigned char** text)
2
{
3
  *text = alle_texte[nr];
4
}
5
6
void print_lcd(void)
7
{
8
  unsigned char *ausgabe;
9
10
  get_text( 1, &ausgabe );
11
  
12
  ...
13
}

Aber, da du nur 1 Ergebnis hast, musst du das nicht so kompliziert 
machen. Ein einfacher Returnwert tuts auch:
1
// Funktion um das Array auszulesen
2
unsigned char* get_text(unsigned char nr)
3
{
4
  return alle_texte[nr];
5
}
6
7
void print_lcd(void)
8
{
9
  unsigned char *ausgabe;
10
11
  ausgabe = get_text( 1 );
12
  
13
  ...
14
}

> Ich bekomme das aber irgendwie nicht richtig hin. Hat jemand Ahnung was
> ich falsch mache?

Dein Fehler: Du hast kein C-Buch. bzw. wenn du eines hast, dann hast du 
es nicht durchgearbeitet.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Peter H. schrieb:
> unsigned char text_01[5] = "Peter";
"Peter" hat 6 Zeichen, wenn man die bei C übliche abschliessende Null 
mit berücksichtigt...

> unsigned char alle_texte[3];
>  alle_texte[0] = &text_01;
Dir ist die Sache mit den Pointern noch nicht so geläufig, oder?

> unsigned char alle_texte[3];
Damit wird Speicherplatz für genau 3 Zeichen (aka Byte) reserviert.

>  &text_01;
Das ist ein Pointer, der auf die Adresse also den den Anfang des (nicht 
korrekt terminierten, weil zu kurzen) Strings "Peter" zeigt.


Wenn dir das alles jetzt irgendwie nichts sagt, dann würde ich dir ein 
C-Buch empfehlen.

EDIT: Pech, Zweiter... ;-)

von Karl H. (kbuchegg)


Lesenswert?

Lass den Compiler für dich arbeiten! Der kann wunderbar Strings für dich 
abzählen und im Gegensatz zu dir macht er keine Fehler. Denn du hast auf 
die abschliessenden \0 Bytes in den Strings vergessen.
1
unsigned char text_01[] = "Peter";
2
unsigned char text_02[] = "Klaus";
3
unsigned char text_03[] = "Ute";

und wozu brauchst du die INit Funktion? Braucht kein Mensch. Wieder: 
Lass den Compiler für dich arbeiten!
1
unsigned char text_01[] = "Peter";
2
unsigned char text_02[] = "Klaus";
3
unsigned char text_03[] = "Ute";
4
5
unsigned char* alle_texte[] = { text_01, text_02, text_03 };

fertig. Der Compiler setzt alles richtig auf ohne dass du daran denken 
musst eine Funktion aufzurufen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Lass den Compiler für dich arbeiten!
Karl Heinz Buchegger schrieb:
> Wieder:
> Lass den Compiler für dich arbeiten!
Steht auch alles ausführlich im bereits erwähnten C-Buch...  ;-)

von Georg G. (df2au)


Lesenswert?

Was mir auffällt (bei vielen Beiträgen hier im Forum): Der Compiler 
wirft Warnungen per Dutzend, wenn man die Konstrukte des OP nimmt. Warum 
ist es üblich, die zu ignorieren? Wenn Code ohne Warnungen und Fehler 
compiliert wird und es dennoch knallt, kann/sollte man fragen.

von Peter H. (Gast)


Lesenswert?

Hallo zusammen,

vielen Dank für Eure Tips. Beim Probieren ist mir auch aufgefallen, dass 
ich immer ein Zeichen mehr Platz lassen muss um eine Textausgabe zu 
machen da ich in der Ausgabefunktion auch auf eine "0x00" warte.
So wie das "Karl Heinz Buchegger" beschrieben hat klappt es ja echt sehr 
komfortabel.

Vielen Dank an alle die mir unter die Arme gegriffen haben.

Schönes Wochenende und viele Grüße,

Peter

von Karl H. (kbuchegg)


Lesenswert?

Peter H. schrieb:
> Hallo zusammen,
>
> vielen Dank für Eure Tips. Beim Probieren ist mir auch aufgefallen, dass
> ich immer ein Zeichen mehr Platz lassen muss um eine Textausgabe zu
> machen da ich in der Ausgabefunktion auch auf eine "0x00" warte.

Du brauchst gaaaaaanz dringend ein C-Buch!


Alle Strings in C haben IMMER hinten als letztes Zeichen ein \0 Byte. 
Immer! So sind Strings in C definiert. Ein leerer String

  ""
besteht aus 1-nem Byte. Eben wegen dem \0 Byte, welches einen String 
abschliesst.
Der String "hallo" besteht aus 6 Bytes. Davon sind 5 Bytes für die 
Zeichen und 1 Byte für das abschliessende \0 Byte.

  char t[5];

  strcpy( t, "hallo" );

geht schief, weil eben 6 Bytes nicht in ein Array der Länge 5 passen.


Das sind aber alles C-Grundlagen. Und ja: Strings sind die erste große 
Hürde der C-Neulinge. Und sie sind beileibe nicht die schwierigste, die 
es zu meistern gilt.

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.