www.mikrocontroller.net

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


Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
char buffer [5];

if (Option 1)
{
  buffer = {"Text1"};
}
else if (Option 2)
{
  buffer = {"Text2"};
}
else if (Option 3)
{
  buffer = {"Text3"};
}

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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

  char * OutText;

  if (Option 1)
  {
    OutText = "Text1";
  }
  else if (Option 2)
  {
    OutText = "Text2";
  }
  else if (Option 3)
  {
    OutText = "Text3";
  }

  lcd_send_string( OutText );


Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
char buffer[5];
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
  if (Option_1)
  {
    lcd_send_string( "Text1" );
  }
  else if (Option_2)
  {
    lcd_send_string( "Text2" );
  }
  else if (Option_3)
  {
    lcd_send_string( "Text3" );
  }

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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" );
>   }
> 

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.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wozu gibt es mehrdimensionale Arrays :)

#include <stdio.h>
#define ANZAHL 3
#define STRING_SIZE 6

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;
}

Autor: Tom M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
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!

Autor: Hans (Gast)
Datum:

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

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
>
> 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?
int foo( int Option )
{
  char * Texte[] = { "Text1",
                     "Text2",
                     "Text3" };

  lcd_string( Texte[ Option ] );
}

>
> 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main(){
  char **ptr;
  int i;
  ptr=(char**)malloc(5*sizeof(char*));
  for(i=0;i<5;i++){
    *(ptr+i)=(char*)malloc(20*sizeof(char));}
  *ptr=strcpy(ptr[0],"teststring1");
  *(ptr+1)=strcpy(ptr[1],"teststring2");
  *(ptr+2)=strcpy(ptr[2],"teststring3");
  *(ptr+3)=strcpy(ptr[3],"teststring4");
  *(ptr+4)=strcpy(ptr[4],"teststring5");
  for(i=0;i<5;i++){
    printf("%s\n",*(ptr+i));}
  for(i=0;i<5;i++){
    free(*(ptr+i));}
  free(ptr);
        return EXIT_SUCCESS;
}

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

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ] );
> }

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
the more the merrier ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.