Variable in string Funktion übergeben

Gast #3490393
Lesenswert?

Hallo Leute,

seit einigen Wochen beschäftige ich mit dem Thema LCD am 
Mikrocontroller.
Nach einigen einsamen Stunden am Rechner ist es mir auch gelungen texte 
an dem LCD auszugeben.

Zum Problem: Um einen ganzen String an das LCD zu senden, habe ich 
mittels Pointer gearbeitet.
1
void lcd_text(unsigned char *zeile1,unsigned char *zeile2)
2
{
3
  lcd_line1();                    //cursor nach links in zeile 1
4
  while (*zeile1)                 //schleife solange zeichen vorhanden
5
  {
6
    lcd_schreiben(*zeile1++);   //ein zeichen weiter schreiben 
7
  }
8
  lcd_line2();                    //cursor nach links in zeile 2
9
  while (*zeile2)                 //schleife solange zeichen vorhanden
10
  {
11
    lcd_schreiben(*zeile2++);   //ein zeichen weiter schreiben
12
  }
13
  
14
}

Das funktioniert auch wie folgt:
1
void main(){
2
lcd_text("Vielen Dank!","Schon mal!");
3
}
Ich möchte allerdings jetzt z.B die Temperatur anzeigen lassen, wie 
folgt:
1
void main(){
2

3
char temp = 15;
4

5
lcd_text("Temperatur",temp);
6
}
wie muss ich temp schreiben bzw. umwandeln?
#3490409
Lesenswert?

Zualler erst mal hast du dir die Basisfunktion ungeschickt geschrieben.

Das du eine Funktion hast, die 2 Strings auf einmal ausgeben kann, ist 
gut. Aber du hast nicht gesehen, dass da 2 mal die noch primitivere 
Basisfunktion "gib 1 String aus" drinnen steckt.
1
void lcd_string( const char* str )
2
{
3
  while( *str )
4
    lcd_schreiben( *str++ );
5
}

damit schreibt sich dann dein lcd_text als
1
void lcd_text(unsigned char *zeile1,unsigned char *zeile2)
2
{
3
  lcd_line1();                    //cursor nach links in zeile 1
4
  lcd_string( zeile1 );
5

6
  lcd_line2();                    //cursor nach links in zeile 2
7
  lcd_string( zeile2 );
8
}

Noch hat sich nichts verändert.
Aber die Dinge ändern sich. Denn um
1
lcd_text("Temperatur",temp);
das hier zu tun, ist die Funktion lcd_text unbrauchbar. Die kann ja 2 
Strings ausgeben. Aber nicht einen String und einen int. Einen String 
könntest du (dank lcd_string) ausgeben, aber um den int auszugeben 
brauchst du eine weitere Hilfsfunktion, die genau das (und nicht mehr) 
kann: einen int ausgeben.

FAQ
(gleich der erste Punkt)

und der Rest ist wieder ein Kinderspiel. Du hast eine Funktion, die 
einen String ausgeben kann - du hast eine Funktion die einen int 
ausgeben kann - was also ist naheliegender, als mit diesen beiden 
Hilfsfunktionen (und den entsprechenden lcd_line Funktionen) eine 
weitere Funktion zu bauen
1
void lcd_wert( const char* label, int wert )
2
{
3
  lcd_line1();
4
  lcd_string( label );
5

6
  lcd_line2();
7
  lcd_int( wert );
8
}

und damit kannst du dann im Hauptprogramm das hier machen
1
...
2
   lcd_text( "Vielen Dank!", "Schon mal!" );
3
   lcd_wert( "Temperatur", temp );
4
...


Die Kunst besteht momentan auf dieser Ebene noch darin, sich selbst 
einen kleinen universell einsetzbaren Baukasten an Basisfunktionen zu 
machen, aus dem sich dann komplexere Sachen zusammensetzen lassen.
Deine 'Basisfunktion' war noch nicht primtiv genug, daher sind da keine 
Bausteine für andere Basisfunktionen abgefallen. Mit dem lcd_string und 
der noch von dir zu schreibenden lcd_int hat sich das geändert.
Gast #3490412
Lesenswert?

Naja, lcd_text erwartet einen String (char *), also kannst du keinen 
char übergeben, und auch keinen int oder sonstwas.
(Ich würd übrigens das unsigned weglassen, hier gehts ja um Text)

Du musst also aus deinem "char temp" irgendwie einen String formen.
Ein Tipp: schau dir mal die Standard-Funktion itoa() an.
Zusätzlich musst du dir Speicher reservieren, den du dan an atoi() 
übergibst damit diese hineinschreiben kann.
Gast #3490503
Lesenswert?

Vielen dank erstmal für die schnelle und gute Antwort, buchegg. Das 
leuchtet ein!

Jetzt habe ich aber noch folgendes Problem:
1
int lcd_int(int wert)
2
{
3
int buffer[10];
4
itoa(wert,buffer,10);
5
return(buffer);
6
}

So sollte ja die lcd_int aussehen, allerdings kennt Ride7 trotz include 
von stdlib, die itoa nicht??
Gast #3490527
Lesenswert?

Oliver schrieb:
> Bei dem Code hast du zwei Probleme ;)

Drei...

Simon T schrieb:
> Jetzt habe ich aber noch folgendes Problem:
> int lcd_int(int wert)
> {
> int buffer[10];

Wenn du einen String willst, sollte das ein Array aus char sein, nicht 
int.

> itoa(wert,buffer,10);
> return(buffer);

Autsch! Du gibst hier einen Zeiger zurück auf einen Puffer, der bei 
Rückkehr auf die Funktion freigegeben wird und daher im Aufrufer 
tunlichst nicht zu verwenden ist.

> }
>
> So sollte ja die lcd_int aussehen, allerdings kennt Ride7 trotz include
> von stdlib, die itoa nicht??

Dann wird "Ride7" (was immer das sein mag) die nicht unterstützen. Es 
ist keine Standard-Funktion.
Gast #3490578
Lesenswert?

Sorry bin seit 10 Uhr am programmieren, langsam gehts berg ab!
1
char lcd_int(int wert)
2
{
3
char buffer[10];
4
sprintf(buffer,"%d",wert);
5
return(buffer);
6
}

so Probleme beseitigt, bis auf eins. Wie soll ich den Wert zurück geben?
#3490584
Lesenswert?

Rolf Magnus schrieb:

> Dann wird "Ride7" (was immer das sein mag) die nicht unterstützen. Es
> ist keine Standard-Funktion.


Schon richtig, ist keine Standardfunktion.
Sie könnte auch _itoa heissen. Dann wäre sogar die Namensgebung ganz 
korrekt. Wenn auch das nicht, dann wird man wohl zum aussersten greifen 
müssen und die Ride7 Doku zur Rate ziehen. Oder man schreibt sie sich 
selber. Ist ja nicht schwer (und da dieses so ist, wundert es mich, dass 
es nichts gleichwertiges in Ride7 [was immer dieses Ride7 auch sein 
soll] gibt)

@Simon
> So sollte ja die lcd_int aussehen

Nein. Eigentlich nicht.
Sinn der Funktion lcd_int ist es, etwas auf das LCD auszugeben! In 
völliger Analogie zu den anderen lcd_.... Funktionen.
Deine Funktion gibt aber nichts aus! Scheinbar hast du den Link in die 
FAQ entweder nicht gesehen oder nicht gelesen.
1
void lcd_int(int wert)
2
{
3
  char buffer[10];
4

5
  itoa(wert, buffer, 10);
6
  lcd_string( buffer );
7
}
(bzw. dann eben die Funktion, die du als Ersatz für itoa hernimmst.)


in deinem Baukasten:
1
lcd_string     gibt einen String auf das LCD aus
2
lcd_int        gibt einen int auf das LCD aus
mit der besonderen Betonung auf 'gibt ... aus'. Und wenn diese 
Konvention in deinem Baukasten gilt, dann sollen die Funktionen dann 
auch genau das tun. Und zwar möglichst einheitlich, damit man sich das 
auch merken kann.
Gast #3490599
Lesenswert?

Ok, sprintf ist natürlich die Holzhammermethode.
Nicht dass ich davon abraten würde, das musst du wissen ob du die 
Resourcen hast. Ich selbst benutz es mittlerweile auch, weils mir zu 
blöd ist jeweils 10 verschiedene Interfaces für Lcd und UART zu haben, 
je nachdem was ich ausgeben will.
Mit der printf-Familie hast du ein einziges Interface und kannst dem 
alles übergeben.


Aaaaaber: wenn du anscheinend vor hast, sprintf zu nutzen dann ist die 
Funktion lcd_int obsolet.
Wenn das printf-Zeugs dazugelinkt wird hast du nicht mehr das Problem, 
verschiedene Funktionen für verschiedene Datentypen schreiben zu müssen. 
Dann brauchst du keine lcd_text() oder lcd_wert() mehr.
Du kannst dir eine Funktion anlegen die alles ausgeben kann.

Aber der dritte Weg ist, eine itoa() selber zu schreiben. Das ist kein 
Hexenwerk und könnt dich weiterbringen.
Gast #3490623
Lesenswert?

So vielen vielen Dank! Es läuft!
1
void lcd_int(int wert)                  //Funktion zum umwandeln von Int in String
2
{
3
char buffer[16];                        //String mit 16 Stellen
4
sprintf(buffer,"%d",wert);              // "drucken" des wertes vom Typ Int in die Variable "buffer"
5
lcd_string(buffer);
6
}

hatte nen leichtes Brett vorm Kopf :).

Jetzt ist Feierabend für heute!

Schönen Abend
#3490634
Lesenswert?

Simon T schrieb:

Nicht das ich ein Problem damit habe, aber

> char buffer[16];                        //String mit 16 Stellen

erstens sind es nur 15 Stellen.
Aber. Wieso 15? Wie gross ist denn ein int auf deinem System?

Wenn der, was auf einem AVR üblich ist, 2 Bytes groß ist (also 16 Bit), 
dann hat der einen Wertebereich von -32768 bis 32767. Das sind als 
maximal 5 Stellen für die Ziffern und noch 1 Stelle für ein mögliches 
negatives Vorzeichen. Macht in Summe 6 benötigte Stellen, also ist ein 
Array der Länge 7 ausreichend.

Wie gesagt, es wird nicht viel ausmachen, da ein paar Bytes zuviel 
anzulegen und wenn man die Ausgabe etwas freier macht, dann schadet das 
auch nicht. Aber mit einem 16-Bit int ist es in DIESER Funktion 
technisch nicht möglich, mehr als 6 druckbare Zeichen zu erhalten.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren