Sonderzeichen mit sprintf

OP #1099732
Lesenswert?

Moin!

Ich möchte auf meinem Display folgendes darstellen:

Winkel: 123,3°

Mein Problem ist das °-Zeichen.

Mein vorgehen ist das folgende:
1
sprintf(text, "Winkel: %5.1f°", Winkel);

auch die Version
1
sprintf(text, "Winkel: %5.1f" "°", Winkel);
fuktioniert auch nicht.

Leider will das aber nicht. Was mache ich denn falsch?

Die Entwicklungsumgebung ist WinAVR mit dem AVRStudio. Der µC ist ein 
AT90CAN128 und das Display ist ein eDIP240-7 über I2C angesteuert.

Vielen Dank schon einmal für die Antworten!

Gruß,

Sven
OP #1099817
Lesenswert?

Moin!

Die Option %c funktioniert nicht. Gibt es die denn überhaupt im GCC 
Compiler? Ich kenne die nur unter C++.
Laut Datenblatt sol das °-Zeichen Lower 8 und Upper 240 sein (dez). Das 
müsste doch 248 ergeben, oder?

weder
1
sprintf(text, "Winkel: %3.1f %c", Winkel, 248);
noch
1
sprintf(text, "Winkel: %3.1f %c", Winkel, '°');

führen zum Erfolg.

Irgendwie komisch...

Noch jemand eine Idee?

Gruß,

Sven
Gast #1099844
Lesenswert?

Hi,

ich hab so was mal in Bascom gemacht. Mein Code dazu sieht so aus:

Befehle = "#ZF3,#ZL10,70,Temperatur:  xx.x{248}C{013}"

xx.x wird später mit ASCII zeichen aufgefüllt und die 248 ist das 
°-Zeichen.
Bei mir ist das die Schriftart 3 aus dem Datenblatt. Benutzt du 
vielleicht eine Andere, in der das °-Zeichen nicht vorkommt?

Ansonsten sieht das mit dem %c und 248 für mich erstmal richtig aus.

Viele Grüße
Gast #1099883
Lesenswert?

Sonderzeichen werden in einem C-String normalerweise mit Backslash, 
führender Null und dem Oktalwert des Zeichens angegeben. Wenn dein '°' 
auf deinem Display den Dezimalwert 248 hat, sollte eigentlich
1
 sprintf(text, "Winkel: %3.1f\0370", Winkel);
zum Ziel führen.

Die Umrechnung Dezimal-Oktal macht übrigens ganz bequem der 
Windows-Rechner in der wissenschaftlichen Ansicht. Im Dezimal-Modus 
deine Dezimalzahl eingeben, links dann Okt statt Dez anklicken, 
Umrechnung fertig.

Welchen (Dezimal-)Wert das Grad-Zeichen wirklich hat, lässt sich leicht 
feststellen, schick' einfach alle Werte von 0-255 an das Display.
Gast #1099894
Lesenswert?

Hi

>Welchen (Dezimal-)Wert das Grad-Zeichen wirklich hat, lässt sich leicht
>feststellen, schick' einfach alle Werte von 0-255 an das Display.

Oder im Datenblatt nachsehen. Sollte 0xDF sein.

MfG Spess
Gast #1099961
Lesenswert?

Ich habe gerade im HD44780-Datenblatt nachgeschaut. Falls dein Display
einen dazu kompatiblen Controller ohne zusätzlichen µC zur Umsetzung von
Zeichencodes hat, ist 0xDF richtig, wie spess53 oben geschrieben hat.

Also so:
1
  sprintf(text, "Winkel: %5.1f\xdf", winkel); // hex

oder so:
1
  sprintf(text, "Winkel: %5.1f\337", winkel); // okt

oder (umständlich) so:
1
  sprintf(text, "Winkel: %5.1f%c", winkel, 223); // dez

> Laut Datenblatt sol das °-Zeichen Lower 8 und Upper 240 sein (dez).
> Das müsste doch 248 ergeben, oder?

Die 248 ist der Code für ° in der alten IBM-Zeichencodierung (unter
DOS). Wenn das im Datenblatt des Displays so steht, dann ist es
vielleicht doch eines der intelligenteren. Um welchen Typ handelt es
sich denn?

Kobaltchlorid schrieb:
> sprintf(text, "Winkel: %3.1f\0370", Winkel);

Nur zur Info: Die 0 nach dem Backslash ist zuviel. Oktale
Zeichenkonstanten dürfen maximal 3 Ziffern enthalten.

H.joachim Seifert schrieb:
> kommt aufs Display an.
> sprintf (lcd_buffer,"%2uß",KTY10);         //Temperatur anzeigen

ß hat in der Zeichencodierung nach ISO 8859-1 und -15 den Code 223 bzw.
0xdf, was der HD44780 als ° darstellt (s.o.).

@Sven W.:

Welches Zeichen wird den statt des ° auf dem Display angezeigt?
Gast #1099994
Lesenswert?

> Nur zur Info: Die 0 nach dem Backslash ist zuviel. Oktale
> Zeichenkonstanten dürfen maximal 3 Ziffern enthalten.

ich habe die Version mit führender Null aus irgendeinem C-Buch, weiss 
jetzt aber nicht mehr, aus welchem. Ich programmiere mit CodevisionAVR, 
da funktioniert es ausschliesslich mit führender Null, auch bei 
dreistelligen Oktalzahlen. Interessanterweise funktioniert aber auch 
\xF8.

[c] "Test\0370 Test\370 Test\xF8" /[c]

wird bei mir angezeigt als: Test° Test70 Test°

In der Codevision-Doku steht überhaupt nichts zu dem Thema. Ich war 
deshalb der Meinung, dass die Version mit vorangestellter Null auch bei 
größeren Oktalzahlen gängiger Standard ist.
Gast #1100002
Lesenswert?

> Ich programmiere mit CodevisionAVR, da funktioniert es ausschliesslich
> mit führender Null, auch bei dreistelligen Oktalzahlen.

Dann ist dieser Compiler nicht standardkonform.

> "Test\0370 Test\370 Test\xF8"
>
> wird bei mir angezeigt als: Test° Test70 Test°

Interessant. Ich habe gerade
1
  printf("Test\0260 Test\260 Test\xb0\n");

mit dem GCC auf dem PC ausprobiert. Den Zeichencode für das ° habe ich
angepasst, damit er zu dem auf ISO 8859-15 eingestellten Ausgabefenster
passt. Man erkennt übrigens schon in der Einfärbung von \0260 durch die
Forensoftware, wie der Hase läuft.

Die Ausgabe sieht wie erwartet so aus:
1
Test0 Test° Test°

Die 0 nach dem ersten Test ist die letzte 0 in \0260, das Zeichen \026
ist nicht darstellbar und wird deswegen bei der Ausgabe unterdrückt.
OP #1100153
Lesenswert?

Moin!

Vielen Dank für Eure Hilfe!
Die Sache mit dem Backslash habe ich ganz vergessen gehabt, das war die 
Lösung!

Die richtige Zeile lautet alse:
1
float Winkel;
2
sprintf(Text, "Winkel: %5.1f\xF8", Winkel);

Die 0xF8 stehen für meine 248.

Warum mault eigentlich der Compiler mit der folgenden Aussage:
warning: format '5.1f' expects type 'double', but argument 3 has type 
'float'
Ich dachte immer, %f wäre für float!
Es funktioniert ja auch, aber mich interessiert die Warnung trotzdem...

@yalu: Ja, es ist ein (mehr oder besser mehr weniger) intelligentes 
Display. Es ist das eDIP240-7 (http://lcd-module.de/deu/dip/edip.htm). 
Das Datenblatt findest Du auch auf der Seite.
Prinzipiell ist das Display recht nett, aber es ist leider recht 
langsam.

Gruß,

Sven
Moderator Persönliche Seite #1100201
Lesenswert?

Sven W. wrote:

> Warum mault eigentlich der Compiler mit der folgenden Aussage:
> warning: format '5.1f' expects type 'double', but argument 3 has type
> 'float'
> Ich dachte immer, %f wäre für float!

Nein, ist double.  float konnte man früher bei variablen Argumentlisten
auf Grund der argument promotion Regeln nicht transportieren.  Mit
modernen variablen Argumentlisten geht das allerdings, und du musst
explizit nach (double) casten.

> Es funktioniert ja auch

Zufällig, weil im AVR-GCC sizeof(float) == sizeof(double) ist.

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