Guten Morgen zusammen,
Ich habe mal eine frage zum "sprintf" Befehl.
Und zwar möchte ich auf meinem LCD Belüftung schreiben.
bei diesem Code:
1
set_cursor(0,2);
2
sprintf(Out,"Bel\x5Fftung");
3
lcd_string(Out);
erhalte ich folgende warnung:
"warning: hex escape sequence out of range"
Also um ein "ü" darzustellen muss ich mit dem "\x" + "5F" quasi die
HEX-Zahl in den string packen.
Wenn ich das so compiliere steht auf dem LCD
"Bel_tung" Der Unterstrich deutet nur an das dort ein Komplett schwarze
Kästchen ist.
Wie man dadran sieht fehlt das "f" von Belüftung und das "ü" wird nicht
dargestellt. Der fehler kommt irgendwie daher das bei dem
"Bel"\x5F"ftung"
das kleine "f" noch zu diesem HEX-Umwandlungs-Befehl(?!) genommen wird.
(Wie nennen man diesen Backslash-Umwandlungsteil eigentlich?
Denn wenn ich in dem Code:
1
set_cursor(0,2);
2
sprintf(Out,"\x5F");
3
lcd_string(Out);
schreibe dann wird mir ein "ü" angezeigt.
Vieleicht kann mir da jemand schnell helfen da ich nicht genau weiss
nach was ich gucken soll da ich nicht weiss wie der "\x"-teil überhaupt
heißt.
Gruß
Sebastian
Sebastian Brünsing schrieb:> dargestellt. Der fehler kommt irgendwie daher das bei dem> "Bel"\x5F"ftung"> das kleine "f" noch zu diesem HEX-Umwandlungs-Befehl(?!) genommen wird.
Du hast das Problem erkannt.
> (Wie nennen man diesen Backslash-Umwandlungsteil eigentlich?
Keine Ahnung. Allgmein sind das Escape Sequenzen. Ob die
Hex-Ausgabe-Escape-Sequenz einen eigenen, kurzen Namen hat, weiß ich
aber nicht auswendig.
> Vieleicht kann mir da jemand schnell helfen da ich nicht genau weiss> nach was ich gucken soll da ich nicht weiss wie der "\x"-teil überhaupt> heißt.
Die Lösung besteht darin, dass der Compiler automatisch Strings, die
aufeinander folgen, zusammenhängen muss
1
sprintf(Out,"Bel""\x5F""ftung");
Meistens macht man das so
1
#define CHAR_UE "\x5F"
2
3
sprintf(Out,"Bel"CHAR_UE"ftung");
dann wirds auch an der Verwendungsstelle etwas klarer.
Eine andere Möglichkeit besteht darin, dass man sich die lcd_string
Funktion pimpt, so dass die ein 'ü' im Text gegen 0x5F austauscht. Dann
braucht man an der verwendenden Stelle überhaupt nichts tun, der
'LCD-String-Treiber' erledigt die Anpassung
1
voidlcd_string(constchar*text)
2
{
3
charc;
4
5
while((c=*text++)){
6
if(c=='ü')
7
lcd_data(0x5F);
8
else
9
lcd_data(c);
10
}
11
}
12
13
14
sprintf(Out,"Belüftung");
15
lcd_string(Out);
Dasselbe natürlich auch noch für ä ö ß und was es sonst noch so gibt.
PS: Wenn die lcd_data Funktion (oder wie auch immer die bei dir heißt)
ausschliesslich dazu benutzt wird, Zeichen auszugeben, dann kann man die
Ersetzung sinnvollerweise auch dort hinein verpflanzen. Zur Not kann man
sich auch immer noch eine eigene Zeichen-Ausgabe Funktion schreiben, die
nur diese Ersetzung macht und dann lcd_data aufruft und von überall her
benutzt wird, wenn es gilt ein Zeichen auszugeben
vielleicht gibt's auch eine LCD-Funktion, die nicht Characterstrings
verdaut, sondern reine Bytes, die dann 1:1 ans LCD weitergegeben
werden.Irgendwann vor ein paar Wochen hatte ich doch schon mal so eine
ähnliche Frage beantwortet.
Ja Danke Karl Heinz,
das werde ich nachher direkt mal ausprobieren. das mit dem aussondieren
und dann halt später die automatische umwandlung von ä ü ö
Vielen Dank
Woher kommt eigentlich dieser Unsinn, einen fixen Text erst einmal in
ein char Array umzukopieren, nur um dann damit die Ausgabefunktion
aufzurufen?
1
set_cursor(0,2);
2
sprintf(Out,"Belüftung");
3
lcd_string(Out);
so ist es doch viel kürzer und auch schneller
1
set_cursor(0,2);
2
lcd_string("Belüftung");
sprintf brauchst du nur dann, wenn in den Text auch noch Ausgaben zb in
Form von Zahlenwerten eingebaut werden sollen (und die auch nur dann,
wenn du spezielle Formatierungswünsche hast)
XXXXX schrieb:> Versuch doch mal:> Bel\x5f\ftung> Bin mir nicht ganz sicher, aber einen Versuch ist es wert.
Nein, eigentlich ist das keinen Versuch wert.
Da haben die Gründerväter von C ganz einfach geschlafen und nicht
spezifiziert bzw. gar nichts dafür vorgesehen, woran der Compiler
erkennen kann, dass eine direkt angegebene Hex-Zahl definitiv zu Ende
ist. Solange der nächste Buchstabe zur Hex-Zahl gehören könnte, tut er
das auch. Das f in 'Belüftung' ist eine mögliche Ziffer einer Hex Zahl
und gehört damit zur Hex-Zahl dazu, ob du willst oder nicht.
Aus der Tatsäche, dass das jetzt seit nahezu 40 Jahren nicht akut genug
war, um die Normaungsgremien auf Abhilfe sinnen zu lassen, kann man wohl
auch ableiten, dass es in der Praxis kein allzugroßes Problem darstellt.
Gibt ja noch ne Menge mehr Sonderzeichen, die in der Codierung nicht mit
ASCII übereinstimmen (Umlaute gross und klein, °, µ etc).
Wenn du Platz genug hast: komplette Zeichsatztabelle hinterlegen
(128..255 reicht eigentlich) und in der Ausgaberoutine den tatsächlichen
Zeichencode holen.
Ansonsten musst du eben jeden Sonderfall einzeln bearbeiten.
Karl heinz Buchegger schrieb:> Woher kommt eigentlich dieser Unsinn, einen fixen Text erst einmal in> ein char Array umzukopieren, nur um dann damit die Ausgabefunktion> aufzurufen?>>
Gute Frage xD. Das hab ich einmal zu kopiert und war dem noch nicht
nachgegangen. ich wusste garnicht das es anders auch geht ich dachte
beim sprintf würde noch irgendwas umgewandelt.
Danke fuer den Tipp, ich bin ja noch am lernen :)
> das werde ich nachher direkt mal ausprobieren. das mit dem aussondieren> und dann halt später die automatische umwandlung von ä ü ö
Beim Aussondieren kannst Du in eine Falle laufen: Du hängst vom
Zeichensatz ab, und der wird häufig UTF-8 sein. Dann aber wird ein „ü“
mit 2 Bytes dargestellt (0xC3 0xBC)¹, und Du müsstest das auch noch
erkennen.
Die Version mit CHAR_UE umschifft das Problem.
(¹ und Apple kodiert es nochmal anders - ein „u“ und eine Diaeresis.)
Was auch funktionieren kann (hängt evtl. vom Editor/Compiler ab)
sprintf( Out, "Bel§ftung");
Den Hex-Code für das darzustellende Zeichen (LCD-Zeichensatz) mit Alt
und Nummernblock dezimal eingeben.
0xF5 ->245dez
Alt halten, dann 245 eingeben. Kommt auf dem Bildschirm natürlich das
falsche Zeichen.
@ Karl heinz Buchegger (kbuchegg) (Moderator)
>Woher kommt eigentlich dieser Unsinn, einen fixen Text erst einmal in>ein char Array umzukopieren, nur um dann damit die Ausgabefunktion>aufzurufen?
Aus dem Tutorial wahrscheinlich. Und selbst deine zweite Methode ist auf
dem AVR Unsinn, Stichwort RAM-Verschwendung und pgmspace.h.
1
#include<avr/pgmspace.h>
2
set_cursor(0,2);
3
lcd_string_P(PSTR("Belüftung"));
Werd ich demnächst mal ins Tutorial einbauen.
MfG
Falk
Falk Brunner schrieb:> Werd ich demnächst mal ins Tutorial einbauen.
Bedenke bitte aber auch, dass du es mit Anfängern zu tun hast. Du darfst
nicht gleich mit der ultimativen Lösung ins Haus fallen, damit
überfährst du sie durch zuviel Information auf einmal. Das überblicken
sie dann nicht mehr.
Siehe zb die vielen Fragesteller, die es nicht schaffen, sich aus dem
Tutorial aus dem Abschnitt über Flash-Zugriffe das Arbeiten mit Strings
im Flash herauszulesen (was natürlich zum großen Teil daran liegt, dass
sie nicht wissen wie Strings funktionieren, aber das ist eine andere
Baustelle)
Hc Zimmerer schrieb:> Beim Aussondieren kannst Du in eine Falle laufen: Du hängst vom> Zeichensatz ab, und der wird häufig UTF-8 sein. Dann aber wird ein „ü“> mit 2 Bytes dargestellt (0xC3 0xBC)¹, und Du müsstest das auch noch> erkennen.
Das Problem erschlage man mit der Verwendung eines Nicht-Unicode-fähigen
Zeichensatzes im Editor. Ich habe mir FixedSys im AVR-Studio
eingestellt, Unicode-Sauereien fallen da sofort auf.
Zeichensätze sind unter 'Start' --> 'Alle Programme' --> 'Zubehör' -->
'Systemprogramme' --> 'Zeichentabelle' anzusehen,
Bastelphilipp (Gast) schrub am 09.06.2010 um 10:56:
[Etwas code]
In dieser Art hatte ich das Problem bei einem M50530-basierten Display
erschlagen, die Umlaute waren da etwas merkwürdig im Zeichensatz
verteilt. Nur habe ich die Ersetzung direkt in der LCD-Ausgabe-Routine
versenkt.
Gruß
Jadeclaw.
Jadeclaw schrieb:> Das Problem erschlage man mit der Verwendung eines Nicht-Unicode-fähigen> Zeichensatzes im Editor.
Solange Du sicher bist, dass kein anderer (Du selbst in ein paar Jahren
inklusive) da mit einem anderen Editor rangeht, kannst Du das natürlich
machen.
@ Karl heinz Buchegger (kbuchegg) (Moderator)
>> Werd ich demnächst mal ins Tutorial einbauen.>Bedenke bitte aber auch, dass du es mit Anfängern zu tun hast. Du darfst>nicht gleich mit der ultimativen Lösung ins Haus fallen,
Hab ich das in meinen bisherigen Tuturials gemacht?
MFG
Falk