Forum: Mikrocontroller und Digitale Elektronik Übergeben eines Textstrings in C


von Hans (Gast)


Lesenswert?

Hallo zusammen!

Mal ein Frage zum übergeben eines Textes in C.

Ich habe im Programm einen Teil der soll in Abhängigkeit von einer 
Abfrage einn bestimmten String auf dem LCD ausgeben.

Da ich sehr viele Abfragen habe, könnte ich jetzt jedesmal in jeder 
einzelnen Abfrage die Funktion zum String-ausgeben aufrufen, oder ich 
schreibe den entsprechenden String in eine Variable und gebe am Ende der 
Abfragen eben nur diesen Puffer aus, also ungefähr so:
1
char buffer [5];
2
3
if (Option 1)
4
{
5
  buffer = {"Text1"};
6
}
7
else if (Option 2)
8
{
9
  buffer = {"Text2"};
10
}
11
else if (Option 3)
12
{
13
  buffer = {"Text3"};
14
}
15
16
lcd_send_string (buffer);

Ist das so in der Richtung korrekt, oder kann man die Übergabe so nicht 
machen?

Mir kommt es irgendwie so vor, dass wenn ich in jede if-Anweisung immer 
wieder das   lcd_send_string ("TextX");   reinschreibe, der Code 
wesentlich schnell größer wird - kann das sein? Oder kommt mir das nur 
so vor?

Ist es generell schlecht, Funktionsaufrufe oft im Quelltext zu 
wiederholen, auch wenn sie garnicht aufgerufen werden?


Danke schonmal für die Hilfe!

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:


> Ist das so in der Richtung korrekt, oder kann man die Übergabe so nicht
> machen?

Die Übergabe schon.
Aber die Zuweisungen nicht :-)
Arrays kann man nicht zuweisen.

1
  char * OutText;
2
3
  if (Option 1)
4
  {
5
    OutText = "Text1";
6
  }
7
  else if (Option 2)
8
  {
9
    OutText = "Text2";
10
  }
11
  else if (Option 3)
12
  {
13
    OutText = "Text3";
14
  }
15
16
  lcd_send_string( OutText );

von Mark B. (markbrandis)


Lesenswert?

1
char buffer[5];
2
buffer = {"Text1"};

So schon mal gar nicht. Du möchtest die Funktion strcpy() bzw. strncpy() 
verwenden. Und 5 Zeichen für den "String", aber kein Platz mehr für die 
Null-Terminierung - nicht gut.

von Karl H. (kbuchegg)


Lesenswert?

Bleibt noch zu sagen:
Je nachdem wie der Teil Option 1 etc aussieht, gibt es auch noch andere 
Möglichkeiten. Ideal ist es zb, wenn die Texte im Grunde einfach nur 
durchnummeriert sind, dann kann man ein Pointer Array benutzen.

von Klaus (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> char * OutText;
>
>   if (Option 1)
>   {
>     OutText = "Text1";
>   }
>   else if (Option 2)
>   {
>     OutText = "Text2";
>   }
>   else if (Option 3)
>   {
>     OutText = "Text3";
>   }
>
>   lcd_send_string( OutText );

Oder gleich so:
1
  if (Option_1)
2
  {
3
    lcd_send_string( "Text1" );
4
  }
5
  else if (Option_2)
6
  {
7
    lcd_send_string( "Text2" );
8
  }
9
  else if (Option_3)
10
  {
11
    lcd_send_string( "Text3" );
12
  }

von Karl H. (kbuchegg)


Lesenswert?

Klaus schrieb:

> Oder gleich so:
>
1
>   if (Option_1)
2
>   {
3
>     lcd_send_string( "Text1" );
4
>   }
5
>   else if (Option_2)
6
>   {
7
>     lcd_send_string( "Text2" );
8
>   }
9
>   else if (Option_3)
10
>   {
11
>     lcd_send_string( "Text3" );
12
>   }
13
>

Ja.
Allerdings interpretiere ich den Begleittext zu seiner Anfrage in der 
Richtung, dass er genau das hat, ihn aber die vielen Funktionsaufrufe 
stören und er die zu einem Aufruf aus der if-elseif Leiter rausziehen 
möchte.

von Mark B. (markbrandis)


Lesenswert?

Wozu gibt es mehrdimensionale Arrays :)

1
#include <stdio.h>
2
#define ANZAHL 3
3
#define STRING_SIZE 6
4
5
int main()
6
{
7
  unsigned int i;
8
  char buffer[][STRING_SIZE] = { {"Text1"}, {"Text2"}, {"Text3"} };
9
10
  for(i=0; i<ANZAHL; i++)
11
    printf("Option %d: %s\n", i+1, buffer[i]);
12
13
  return 0;
14
}

von Tom M. (Gast)


Lesenswert?

Damit dir das kostbare RAM bei vielen Strings nicht ausgeht, solltest du 
Strings mit fixem Inhalt im Flash behalten. Natürlich musst du dann 
(deine?)
lcd_send_string() so umbauen, dass sie aus dem Flash und nicht aus dem 
RAM liest. Übergeben tust du ohnehin nur einen Pointer.

Falls du avr-gcc und die avr-libc verwendest: Siehe Doku/manpage zu 
avr/pgmspace.h

von Hans (Gast)


Lesenswert?

Vielen Dank schonmal, ich habe mir die Möglichkeiten jetzt mal 
durchgelesen.

Also:

Karl heinz Buchegger schrieb:
> Klaus schrieb:
>
>> Oder gleich so:
>>>   if (Option_1)
>>   {
>>     lcd_send_string( "Text1" );
>>   }
>>   else if (Option_2)
>>   {
>>     lcd_send_string( "Text2" );
>>   }
>>   else if (Option_3)
>>   {
>>     lcd_send_string( "Text3" );
>>   }
>>

Das hatte ich bisher. Macht es einen Unterschied, eine Funktion mehrmals 
aufzurufen oder ein Variable zu verändern und diese dann am Ende der 
unktion zu übergeben?

Mark Brandis schrieb:
> So schon mal gar nicht. Du möchtest die Funktion strcpy() bzw. strncpy()
> verwenden. Und 5 Zeichen für den "String", aber kein Platz mehr für die
> Null-Terminierung - nicht gut.

OK, das '\0' fehlt, stimmt! Also kann ich ein Array so garnicht 
bschreiben?
Geht es denn mit
1
char buffer[6] = {'T', 'e', 'x', 't', '1', '\n'};
 ?
?

Karl heinz Buchegger schrieb:
> Ideal ist es zb, wenn die Texte im Grunde einfach nur
> durchnummeriert sind, dann kann man ein Pointer Array benutzen

Könntest du mir das evtl. an einem Beispiel klarmachen? Das verstehe ich 
grad nicht so direkt. Mit switch-case oder wie genau?

Mark Brandis schrieb:
> int main()
> {
>   unsigned int i;
>   char buffer[][STRING_SIZE] = { {"Text1"}, {"Text2"}, {"Text3"} };
>
>   for(i=0; i<ANZAHL; i++)
>     printf("Option %d: %s\n", i+1, buffer[i]);
>
>   return 0;
> }

Das ist doch auch quasi, wie Karl es meint, oder? Da könnte ich jetzt 
also mit "buffer [x]" auf die einzelnen Texte zugeifen? Sind das direkt 
strings mit enthaltenem '\n' wegen der doppelten {{ }}?

Tom M. schrieb:
> aus dem Flash und nicht aus dem
> RAM liest

OK, das wäre ne Möglichkeit, aber da weiß ich omentan garnicht, wie ich 
irgndwas ins Flash und so ablege. Benutze auch kein AVR, sondern einen 
MSP.

Danke danke danke!

von Hans (Gast)


Lesenswert?

Sorry für fehlende Buchstaben in meinem Text, meine Tastatur am Laptop 
ist wirklich extrem ausgelutscht!

von Hans (Gast)


Lesenswert?

Achso, nochmal die Frage:

Bilde ich mir das ein, dass mein Quelltext nach dem kompilieren größer 
ist, wenn ich ständig Funktionsaufrufe wiederhole, anstatt am Ende eine 
Variable einmal an die Funktion zu übergeben?

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:

>>> Oder gleich so:
>>>>   if (Option_1)
>>>   {
>>>     lcd_send_string( "Text1" );
>>>   }
>>>   else if (Option_2)
>>>   {
>>>     lcd_send_string( "Text2" );
>>>   }
>>>   else if (Option_3)
>>>   {
>>>     lcd_send_string( "Text3" );
>>>   }
>>>
>
> Das hatte ich bisher. Macht es einen Unterschied, eine Funktion mehrmals
> aufzurufen oder ein Variable zu verändern und diese dann am Ende der
> unktion zu übergeben?

Unterschied machts prinzipiell schon. Allerdings erwarte ich da keine 
dramatischen Veränderungen. Wenn das wirklich alles ist in den einzelnen 
if ist, dann könnte es sogar sein, dass der Compiler die prinzipiell 
gleichen Aufrufe erkennt und den Code entsprechend umbaut.

> OK, das '\0' fehlt, stimmt! Also kann ich ein Array so garnicht
> bschreiben?

Doch. Natürlich. Du musst es nur richtig machen

   strcpy( buffer, "Text1" );

> Geht es denn mit
>
1
> char buffer[6] = {'T', 'e', 'x', 't', '1', '\n'};
 ?
> ?

geht auch (wenn du wieder mal die Größenangabe korrekt gemacht hättest). 
Aber warum so kompliziert? Muss ja nicht sein.

Und noch was: Lass den Compiler Stringlängen abzählen, der macht dabei 
keine Fehler

   char buffer[] = "Text1";

(Das geht hier deswegen, weil das hier eine Initialisierung ist und 
keine Zuweisung!)

Aber im allgemeinen kann man sagen: Bei solchen Buffern - nicht kleckern 
sonder klotzen. Fehler die entstehen weil du einen Buffer zu klein 
dimensioniert hast, sind schwer zu finden.


> Könntest du mir das evtl. an einem Beispiel klarmachen? Das verstehe ich
> grad nicht so direkt. Mit switch-case oder wie genau?
1
int foo( int Option )
2
{
3
  char * Texte[] = { "Text1",
4
                     "Text2",
5
                     "Text3" };
6
7
  lcd_string( Texte[ Option ] );
8
}

>
> Mark Brandis schrieb:
>> int main()
>> {
>>   unsigned int i;
>>   char buffer[][STRING_SIZE] = { {"Text1"}, {"Text2"}, {"Text3"} };
>>
>>   for(i=0; i<ANZAHL; i++)
>>     printf("Option %d: %s\n", i+1, buffer[i]);
>>
>>   return 0;
>> }
>
> Das ist doch auch quasi, wie Karl es meint, oder?

Fast.

> Da könnte ich jetzt
> also mit "buffer [x]" auf die einzelnen Texte zugeifen? Sind das direkt
> strings mit enthaltenem '\n'

Von \n steht da nichts.

von Karl H. (kbuchegg)


Lesenswert?

PS:

Kann es sein, dass du \n und \0 durcheinanderschmeisst?

\n   Zeilenvorschub
\0   0-Zeichen mit dem jeder gültige String in C abgeschlossen wird.

von Hans (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Von \n steht da nichts.

Ups, sorry! Ich meinte natürlich '\0'

Karl heinz Buchegger schrieb:
>> Geht es denn mit
>>> char buffer[6] = {'T', 'e', 'x', 't', '1', '\n'};  ?
>> ?
>
> geht auch (wenn du wieder mal die Größenangabe korrekt gemacht hättest)

Warum ist das jetzt falsch? Sind doch 6 Zeichen, oder was verstehe ich 
grad nicht?

von Karl H. (kbuchegg)


Lesenswert?

Hans schrieb:
> Karl heinz Buchegger schrieb:
>> Von \n steht da nichts.
>
> Ups, sorry! Ich meinte natürlich '\0'
>
> Karl heinz Buchegger schrieb:
>>> Geht es denn mit
>>>> char buffer[6] = {'T', 'e', 'x', 't', '1', '\n'};  ?
>>> ?
>>
>> geht auch (wenn du wieder mal die Größenangabe korrekt gemacht hättest)
>
> Warum ist das jetzt falsch? Sind doch 6 Zeichen, oder was verstehe ich
> grad nicht?

6 Zeichen schon. Aber es ist kein gültiger String! Du hast wieder mal 
auf das \0 vergessen (oder mit \n verwechselt)

Daher: überlass solche Dinge dem Compiler!

   char buffer[] = "Text1 uga uga und noch son Muell";

der zählt die Zeichen für dich, dimensioniert den Buffer groß genug und 
hängt auch noch das \0 hinten drann.

von Hans (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> (oder mit \n verwechselt)

Ja, hab ich!

Karl heinz Buchegger schrieb:
> überlass solche Dinge dem Compiler!

OK, das werde ich machen! Ich danke vielmals!

von guest (Gast)


Lesenswert?

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
5
main(){
6
  char **ptr;
7
  int i;
8
  ptr=(char**)malloc(5*sizeof(char*));
9
  for(i=0;i<5;i++){
10
    *(ptr+i)=(char*)malloc(20*sizeof(char));}
11
  *ptr=strcpy(ptr[0],"teststring1");
12
  *(ptr+1)=strcpy(ptr[1],"teststring2");
13
  *(ptr+2)=strcpy(ptr[2],"teststring3");
14
  *(ptr+3)=strcpy(ptr[3],"teststring4");
15
  *(ptr+4)=strcpy(ptr[4],"teststring5");
16
  for(i=0;i<5;i++){
17
    printf("%s\n",*(ptr+i));}
18
  for(i=0;i<5;i++){
19
    free(*(ptr+i));}
20
  free(ptr);
21
        return EXIT_SUCCESS;
22
}

ich weiß nicht wie man den flash speicher nutzen kann. aber irgendwie so 
wird es vermutlich gehen.

von Hans (Gast)


Lesenswert?

Also besten Dank für den Beitrag, aber das versteh ich garnicht...mit 
Pointer auf Pointer...

Ich habe es jetzt so gemacht, es funktioniert einwandfrei:

Karl heinz Buchegger schrieb:
> int foo( int Option )
> {
>   char * Texte[] = { "Text1",
>                      "Text2",
>                      "Text3" };
>
>   lcd_string( Texte[ Option ] );
> }

von Peter (Gast)


Lesenswert?

guest schrieb:
> ich weiß nicht wie man den flash speicher nutzen kann. aber irgendwie so
> wird es vermutlich gehen.

was wolltest du überhaupt mit dem code erreichen? Zumindest mit flash 
kann ich darin nichts erkennen.

von guest (Gast)


Lesenswert?

>>Karl heinz Buchegger schrieb:201
>> int foo( int Option )
>> {
>>   char * Texte[] = { "Text1",
>>                      "Text2",
>>                      "Text3" };


>Also besten Dank für den Beitrag, aber das versteh ich garnicht...mit
>Pointer auf Pointer...

kein problem.
karls variante tut genau das gleiche. :p
der erste zeiger zeigt auf den eintrag in der liste Text1 Text2 Text3 
usw. mit dem zweiten zeiger lässt sich durch die einzelnen buchstaben 
hüpfen.

beispiel:
möchte man auf das e von Text2 ausgeben, geht das folgender maßen:
printf("%c",*(*(Texte+1)+1));
oder
printf("%c",*(Texte[1]+1);
oder
printf("%c",Texte[1][1]);

möchte man einen string mit %s ausgeben muss man %s nicht den wert 
sondern den zeiger selbst übergeben

printf("%s",*(Texte+1));
wobei auch hier wieder ein:
printf("%s",Texte[1]);
möglich ist.

ich mag letztere schreibweise nicht so gerne deshalb die doppelten 
pointer.


gruß

von Karl H. (kbuchegg)


Lesenswert?

guest schrieb:

> ich mag letztere schreibweise nicht so gerne deshalb die doppelten
> pointer.

guest. Du solltest ganz schnell von deinem Pointertripp wieder runter 
kommen

von guest (Gast)


Lesenswert?

the more the merrier ;)

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.