fprintf %s Formatzeichen oder doch nur char Pointerfehler im 2D-Array?

OP Persönliche Seite #3165615
Hi,

ich experimentiere gerade mit einem kleinen LCD(HD44780) und muss 
feststellen, dass ich mich schon wieder in Pointerarithmetik verstricke, 
oder einfach nicht richtig verstehe, was "fprintf" intern macht.

Ich gebe Mal kurz das Bsp. und sage euch dann was ich erwarte bzw. nicht 
erwarte:
1
const char menue[][16]= {"IP-Adresse:     ", "MIDI-IN-THROU   ", "DMX-UNIVERSE 1  ", "DMX-UNIVERSE 2  ", "DMX-UNIVERSE 3  ", "DMX-UNIVERSE 4  "};
2
const char blend_left[] = "<<--<<--";
3
const char blend_right[] = "-->>-->>";
4

5
fprintf(&lcd_stdout, "%s%s%s",menue[m_item],blend_right, menue[m_item+1]);

Ich erwarte eine Ausgabe wie "IP-Adresse:     -->>-->>MIDI-IN-THROU   "
Bekomme aber einen Mischmasch aus allen Feldern.

Meine Vermutung ist, dass fprintf die Einträge ALLE konkateniert und 
dann aufs Display schreibt. Dieses hat aber nur 2x40 Zeichen und fängt 
dann warscheinlich wieder vorne an zu überschreiben, so dass ich den 
Mist sehe.

Da ich eh alle Leerzeichen reinschupsen muss, habe ich von einem 
Pointerarray a la char *menue[] Abstand genommen.

Könnt *ihr* mir *einen* Schubs *in* die *richtige* Richtung 
*geben?* (und nebenbei sagen, wie man ganze Sätze hier fett bekommt ;)


Ich dachte ich mache mir das Leben einfacher, indem ich nen Wrapper 
nutze:
1
static inline int lcd_putchar(char c, FILE* stream)
2
{
3
  lcd_sendchar(c);
4
}
 aber nun stehe ich da mit dem Halbwissen über fprintf und diese 
Formatzeichen wie %s.

Grüße Oekel
OP Persönliche Seite #3165671
Michael Frangenberg schrieb:
> Das Problem liegt nicht im fprintf, sondern eher daran, dass die Strings
> gar nicht terminiert sind, weil du keinen Platz für die terminierende
> '\0' gelassen hast.
>
1
const char menue[][17]= ...
> An sonsten springt mir gerade nichts ins Auge...

Und genau das wars dann auch schon. Perfekt danke!

Falls mir noch Jemand erklären könnte, warum sich dieser Effekt 
einstellt, wenn ich das Zeichen nicht mit einplane, wäre ich noch einen 
Tick schlauer.
Aber fürs erste bin ich wieder happy!

Grüße Oekel
Gast #3165683
D a v i d K. schrieb:
> Falls mir noch Jemand erklären könnte, warum sich dieser Effekt
> einstellt, wenn ich das Zeichen nicht mit einplane, wäre ich noch einen
> Tick schlauer.

Das sind absolute Grundlagen für die Stringverarbeitung in C.

Es ist so vereinbart, das Strings in C mit einer '\0' terminirt werden.
Daran wird das Ende erkannt.

Wenn du ein
1
fprintf(&lcd_stdout, "%20s%s%s",menue[m_item],blend_right, menue[m_item+1]);
machst, brauchst du in deinen Texten die Leerzeichen am Ende auch nicht 
mehr.
Gast #3165690
Ich korrigiere mich
1
fprintf(&lcd_stdout, "%-16.16s%s%s",menue[m_item],blend_right, menue[m_item+1]);
Es sollen ja 16 Zeichen sein, linksbündig und maximal 16 Zeichen.
OP Persönliche Seite #3165714
Markus M. schrieb:
> Das Thema mit den C-Strings wird hier im Forum einmal die Woche
> durchgekaut. Verwende bitte die Suchfunktion mit "C-String" und lies dir
> den Artikel durch:
> http://www.mikrocontroller.net/articles/String-Verarbeitung_in_C
>
> Grüsse

Du hast natürlich Recht. Nachdem klar war, dass mein Fehler dort lag, 
hätte ich mich erneut ORDENTLICH auf die Suche machen müssen. Zumal die 
Artikel hier wirklich allererste Sahne sind. Sorry, der zweite Post war 
voreilig und faul...

DirkB schrieb:
>
1
fprintf(&lcd_stdout, "%-16.16s%s%s",menue[m_item],blend_right,
2
> menue[m_item+1]);

Danke, eben DAMIT kenne ich mich gar nicht aus, werde mich nun aber 
einlesen.

Grüße Oekel
#3165746
Wenn ein String nicht mit \0 terminiert wird, dann endet er nicht. 
Irgendwo weiter hinten im Speicher wird zufällig ein Null-Byte stehen. 
Der String, den printf dann ausgibt wird genau bis dort gehen. Da Du 
drei Strings ausgibst, wiederholt sich der Fehler drei mal.

printf kann ohne das \0 Zeichen nicht wissen, wo der String endet. Den 
als Parameter wird nicht der ganze String übergeben, sondern ein Pointer 
auf das erste Zeichen. Es wird keine Längen-Angab eübergeben. Ob das 
Array als char[16] oder char[100] deklariert ist, kann printf nicht 
wissen.

Das gilt für alle String Funktionen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.