Hallo zusammen, ich habe den Forenbeitrag ähnlichen Namens anno 2011 durchaus gefunden- dort wird die Frage aber nicht geklärt, sondern ein anders liegender Fehler gefunden. Welchen Zeichensatz nutzt eigentlich AVR-GCC? Konkret ist im Quelltext unter AtmelStudio 6 ein "µ"-Zeichen als Integer "181" vom ATmega angezeigt worden. Nach: http://en.wikipedia.org/wiki/Mu_(letter) könnte das Unicoder oder UTF-8 sein. Auf den ersten Blick klingt beides für den kleinen AVR unglaubwürdig. Oder nutzt AVR-GCC einfach den Zeichensatz des Quellsystems (bei mir Windows 7), d.h. der Source-Code würde auf einem Linux-System anders kompiliert, wenn ich das Zeichen über die Tastatur eingebe und eine direkte Eingabe des Sonderzeichen als Escape-Sequenz mit Hex-Code des Zeichens wäre ratsam? Viele Grüße Nicolas
der Zeichensatz spielt doch überhaupt keine rolle. Das zeichen µ (181) wird einfach als 181 weiter verwendet. Wenn du es per Print ausgibtst dann kommt halt wieder eine 181 raus.
Nicolas S. schrieb: > Konkret habe ist im > Quelltext unter AtmelStudio 6 ein "µ"-Zeichen als Integer "181" vom > ATmega angezeigt worden. Wie zeigt deín Prozessor etwas an? Hast du einen ATMega mit eingebautem Display? Oliver
Natürlich spielt der Zeichensatz eine Rolle. Wenn ich im Quelltext ein char mit dem Inhalt 'µ' erzeuge, ist es durchaus von Bedeutung, welchen Zahlenwert der Kompiler daraus macht - schließlich muß ich meinen Zeichensatz danach auslegen. Eingebaut ist das Display nicht, aber angehängt. Und einen char kann ich ja durchaus als int anzeigen. Muß ich sogar, wenn ich den Zeichensatz entwerfe.
Nicolas S. schrieb: > Natürlich spielt der Zeichensatz eine Rolle. Wenn ich im Quelltext ein > char mit dem Inhalt 'µ' erzeuge, ist es durchaus von Bedeutung, welchen > Zahlenwert der Kompiler daraus macht - schließlich muß ich meinen > Zeichensatz danach auslegen. nein macht es nicht. Er nimmt es so wie es kommt und wenn die es ausgibtst bekommst du es genauso zurück. Das ist wie ein Tonbandgerät, dem ist auch die Sprache egal. Der eigentliche Quellcode ist ASCII. Was in "Strings" steht spielt keine rolle.
Peter II schrieb: > Der eigentliche Quellcode ist ASCII. Was in "Strings" steht spielt keine > rolle. Die DOS-Erweiterung von ASCII ist es schonmal nicht. Da steht "mu" an Stelle 230 und an Stelle 181 ist ein Stück Rahmen. Peter II schrieb: > Das ist wie ein Tonbandgerät, dem ist auch die Sprache egal. Der kleine AVR ist auch kein Tonbandgerät. Tonbandgeräte kenne ich noch. Die haben keinen Zeichensatz. Die haben nur << ■ || > >>, und das auch nur aufgedruckt. Und wenn ich an einem Display einen Zeichensatz habe, der vom AVR erzeugt wird, ist es durchaus von Wichtigkeit, welches Zeichen im Quelltext zu welcher Zahl im char führen, ansonsten müßte ich nämlich jeden Text als Array eingeben. Will ich aber nicht. Mache ich über die Tastatur. Nur bei Sonderzeichen ist es interessant, ob das erzeugte Zeichen für jede Erzeugerplattform gleich ist. Ansonsten ist der Quelltext nicht portabel. Deswegen ist für mich die Kenntnis des von AVR-GCC genutzten Zeichensatzes DOCH interessant. Ich finde es auch nicht schlimm, wenn andere das langweilig finden. Ich aber nicht.
Nicolas S. schrieb: > Peter II schrieb: >> Der eigentliche Quellcode ist ASCII. Was in "Strings" steht spielt keine >> rolle. > > Die DOS-Erweiterung von ASCII ist es schonmal nicht. Da steht "mu" an > Stelle 230 und an Stelle 181 ist ein Stück Rahmen. der µ steht aber nicht als code sondern als String und dort spielt der zeichensatz keine rolle. (er spielt auch im code keine Rolle, nur mekkert der compiler wenn du versucht eine Variabel mit nicht ASCCI zeichen anzulegen) > Und wenn ich an einem Display einen Zeichensatz habe, der vom AVR > erzeugt wird, ist es durchaus von Wichtigkeit, welches Zeichen im > Quelltext zu welcher Zahl im char führen, ansonsten müßte ich nämlich > jeden Text als Array eingeben. Will ich aber nicht. Dabei hilft dir der zeichensatz nicht weiter. Der compieler macht überhaupt keine änderung von zeichen oder Berücksichtigt einen Zeichensatz. Wenn dein Display eine 230 für ein zeichen will, dann musst du im Quelltext eine 230 hinschreiben egal wie das zeichen das aussieht. Der Compieler ändere keine Zeichen, also spielt er Zeichensatz keine Rolle!
Nicolas S. schrieb: > Deswegen ist für mich die Kenntnis des von AVR-GCC genutzten > Zeichensatzes DOCH interessant. Nein, der avr-gcc nimmst wie es kommt. Was dich interessiert, ist, welchen Zeichensatz dein Editor verwendet. Und das lässt sich für gewöhnlich einstellen.
Der (avr-)gcc nutzt überhaupt keinen Zeichensatz. Der bekommt ein Source-File vorgesetzt, in dem er eine char-Konstante mit dem Integer-Wert 181 vorfindet. Welches Zeichen das ist, ist dem Compiler herzlich egal. Der übernimmt diese 181 einfach ins Hex-File. Die Umwandlung des auf deinem Rechener-Bildschirm sichtbaren "µ" in des Char -Wert 181 macht nicht der Compiler, sondern der Editor. Und welchen Zeichensatz der benutzt, ist tatsächlich abhängig vom Betriebssystem, aber auch vom Editorprogramm selber. Oliver
Als C-Programmierer solltest du dir angewöhnen, dass du dich auf den originalen ASCII-Zeichensatz berufen darfst. 7-Bit - Kleinbuchstaben, Großbuchstaben, Ziffern und ein paar Sonderzeichen. Alles darüber hinausgehende, insbesondere was bei gesetztem 8. Bit rauskommt, ist eine Frage von Gottvertrauen, Editor und hängt nicht zuletzt auch davon ab, was dein Ausgabegerät mit diesen Bytes macht.
OK, das heißt also, daß ich mich nicht darauf verlassen kann, daß der AVR-GCC auf jedem Rechner den gleichen Zeichensatz nutzt. (Oder präziser: Die Eingaben der Textdatei außerhalb des kleinen ASCII-Zeichensatzes gleich interpretiert). Dann bleibt für die Eingabe von Sonderzeichen also nur die Nutzung von Escapesequenzen mit dem Zeichen im Oktalcode. Kann ich mit leben. Tastatur wäre mir lieber gewesen. Hex wäre mir auch lieber gewesen. So sinkt eben stufenweise die Lesbarkeit - wenn's nicht besser geht, geht es nicht besser. Aber ob das wirklich nötig ist, wollte ich vorher geklärt wissen. Danke für die Antworten Nicolas
Nicolas S. schrieb: > OK, das heißt also, daß ich mich nicht darauf verlassen kann, daß der > AVR-GCC auf jedem Rechner den gleichen Zeichensatz nutzt. (Oder > präziser: Die Eingaben der Textdatei außerhalb des kleinen > ASCII-Zeichensatzes gleich interpretiert). immer nocht nicht verstanden! Der GCC nutzt keine Zeichensatz, er macht auch auf jeden System das gleiche. Nur wie dein Editor die Quelltext anzeigt kann anders sein. > Dann bleibt für die Eingabe von Sonderzeichen also nur die Nutzung von > Escapesequenzen mit dem Zeichen im Oktalcode. Kann ich mit leben. > Tastatur wäre mir lieber gewesen. Hex wäre mir auch lieber gewesen. wo soll jetzt der unteschied zwischen Hex und Oktalcode sein?
Nicolas S. schrieb: > OK, das heißt also, daß ich mich nicht darauf verlassen kann, daß der > AVR-GCC auf jedem Rechner den gleichen Zeichensatz nutzt. Das ganze hat nichts mit dem gcc zu tun! Ein Compiler ist ein Programm welches eine Eingabedatei 'verwurschtet'. Welche Zeichen-Codes auch immer der Editor dort abgelegt hat, die werden vom Compiler benutzt. Kann es sein, dass du noch nicht gemerkt hast, dass dein C-Programm, so wie du es mit dem Editor schreibst, auch nichts anderes als eine Abfolge von Code-Bytes ist? Dein Editor ist so freundlich und schreibt dir anstelle der Code Bytes, die zugehörigen Zeichen auf den Bildschirm. Aber Code ist Code. Eine C-Datei (oder überhaupt eine Text-Datei)
1 | int main() |
2 | {
|
3 | return 0; |
4 | }
|
ist auf Dateiebene auch nichts anderes als eine Abfolge von ASCII Codes. Der Compiler liest dieses und was auch immer an Codes in einem String vorkommt, das schreibt er so wie es ist, dann auch ins Programm hinein. > Dann bleibt für die Eingabe von Sonderzeichen also nur die Nutzung von > Escapesequenzen mit dem Zeichen im Oktalcode. Kann ich mit leben. Kann man sich organisieren. Zb. Mit Präprozessorhilfe und der Regel, dass der Compiler aufeinanderfolgende String-Literale zu einem einzigen Literal zusammenfassen muss.
Peter II schrieb: > wo soll jetzt der unteschied zwischen Hex und Oktalcode sein? Ganz einfach:
1 | fprintf("\265C.net"); // geht
|
2 | fprintf("\xb5C.net"); // geht nicht.
|
Bei mir nutzt der arm-gcc den Zeichensatz welcher der Shell Einstellung entspricht. Ich vermute der avr-gcc macht's nicht anders.
1 | $ export LANG=de_DE.UTF-8 |
2 | $ vi x.c |
3 | void main(void) |
4 | {
|
5 | char x[] = {"ABCµXYZ"}; |
6 | }
|
7 | $ /opt/gcc-arm-none-eabi-4_7-2013q1/bin/arm-none-eabi-gcc -c x.c |
8 | $ hexdump -C x.o |grep ABC |
9 | 00000060 00 00 00 00 41 42 43 c2 b5 58 59 5a 00 00 00 00 |....ABC..XYZ....| |
10 | |
11 | |
12 | |
13 | |
14 | $ export LANG=C |
15 | $ vi x.c |
16 | void main(void) |
17 | {
|
18 | char x[] = {"ABCµXYZ"}; |
19 | }
|
20 | $ /opt/gcc-arm-none-eabi-4_7-2013q1/bin/arm-none-eabi-gcc -c x.c |
21 | $ hexdump -C x.o |grep ABC |
22 | 00000060 41 42 43 b5 58 59 5a 00 00 47 43 43 3a 20 28 47 |ABC.XYZ..GCC: (G| |
Norbert schrieb: > Bei mir nutzt der arm-gcc den Zeichensatz welcher der Shell Einstellung > entspricht. Nein! Der vi ist in deinem Beispiel derjenige, der einen Zeichensatz benutzt und für die Unterschiede verantwortlich ist.
Norbert schrieb: > Bei mir nutzt der arm-gcc den Zeichensatz welcher der Shell Einstellung > entspricht. Ich vermute der avr-gcc macht's nicht anders. macht er nicht. Der VI nutzt den zeichensatz nicht der GCC. Nicolas S. schrieb: > Ganz einfach: > fprintf("\265C.net"); // geht > fprintf("\xb5C.net"); // geht nicht. oktal muss mit 0 einfangen!
Stefan Ernst schrieb: > Norbert schrieb: >> Bei mir nutzt der arm-gcc den Zeichensatz welcher der Shell Einstellung >> entspricht. > > Nein! > Der vi ist in deinem Beispiel derjenige, der einen Zeichensatz benutzt > und für die Unterschiede verantwortlich ist. Jo, war unklar ausgedrückt! Ich wollte zum Ausdruck bringen, das wenn ich mich in einem UTF8 Environment befinde, man zB kein µ in eine char Variable packen kann. Da gibt's dann so etwas: warning: multi-character character constant [-Wmultichar] Aber du hast Recht, letztlich wird ein 'µ' je nach Env. verschieden im Sourcecode hinterlegt.
Nicolas S. schrieb: > fprintf("\265C.net"); // geht > fprintf("\xb5C.net"); // geht nicht. nachtrag: http://h21007.www2.hp.com/portal/download/files/unprot/fortran/docs/lrm/lrm0035.htm
Peter II schrieb: > Nicolas S. schrieb: >> Ganz einfach: >> fprintf("\265C.net"); // geht >> fprintf("\xb5C.net"); // geht nicht. > > > oktal muss mit 0 einfangen! Nein. Ein Octal-Code in einem String ist ein Backslash mit drei Ziffern dahinter. \265 ist völlig korrekt.
Nicolas S. schrieb: > Ganz einfach: >
1 | > fprintf("\265C.net"); // geht
|
2 | > fprintf("\xb5C.net"); // geht nicht.
|
3 | > |
Und wenn man es so schreibt
1 | #define MUE "\xB5"
|
2 | |
3 | |
4 | ...
|
5 | |
6 | fprintf( MUE"C.net" ); |
dann kann man das dann (meistens) sogar lesen und alle µ auf einem anderen LCD gegen die dort gültigen Codes an einer einzigen Stelle zentral austauschen.
Stefan Ernst schrieb: > Nein. Ein Octal-Code in einem String ist ein Backslash mit drei Ziffern > dahinter. \265 ist völlig korrekt. oh stimmt, bei 3 stellen kann man es so schreiben. Aber dann sollte auch hex genauso gehen. > fprintf("\xb5C.net"); // geht nicht. gcc liefert auch: warning: hex escape sequence out of range [enabled by default] scheint mir irgendwie ein Bug zu sein. Denn fprintf("\xb5 C.net"); funktioniert. Er will scheinbar mehr als 2 zeichen HEX einlesen.
Peter II schrieb: > Stefan Ernst schrieb: >> Nein. Ein Octal-Code in einem String ist ein Backslash mit drei Ziffern >> dahinter. \265 ist völlig korrekt. > > oh stimmt, bei 3 stellen kann man es so schreiben. Aber dann sollte auch > hex genauso gehen. > >> fprintf("\xb5C.net"); // geht nicht. > > gcc liefert auch: > > warning: hex escape sequence out of range [enabled by default] > > scheint mir irgendwie ein Bug zu sein. Denn Hängt damit zusammen das das 'C' noch als Teil des Hex Wertes angesehen wird. Early termination funktioniert. void main(void) { char y[] = "\265C.net"; char z[] = "\xb5""C.net"; }
Karl Heinz Buchegger schrieb: > Kann es sein, dass du noch nicht gemerkt hast, dass dein C-Programm, so > wie du es mit dem Editor schreibst, auch nichts anderes als eine Abfolge > von Code-Bytes ist? Dein Editor ist so freundlich und schreibt dir > anstelle der Code Bytes, die zugehörigen Zeichen auf den Bildschirm. > Aber Code ist Code. Eine C-Datei (oder überhaupt eine Text-Datei)int > main() > { > return 0; > } > ist auf Dateiebene auch nichts anderes als eine Abfolge von ASCII Codes. Nein, unter dem Blickwinkel habe ich es noch nie betrachtet. Für mich wurde aus einem Binärwurst immer erst durch einen definierten Zeichensatz ein lesbarer Text. Also war ich bislang davon ausgegangen, daß ein Compiler/Präprozessor sich die Sachen erstmal wieder in eine Textebene legt, allein um Leerzeichen, Tabs und Zeilenumbrüche zu interpretieren. Kompilerbau hatten wir im Maschinenbaustudium nicht. Sollte es heute abend nicht zu heiß zum nachdenken sein, lasse ich mir den Wurm, der sich durch binärzeugs frißt, und dabei binärkode zu erzeugt, nochmal in Ruhe durch den Kopf gehen.
Norbert schrieb: > Hängt damit zusammen das das 'C' noch als Teil des Hex Wertes angesehen > wird. richtig, aber er sollte eigentlich nur 2 zeichen nach dem \x einlesen.
Peter II schrieb: > Norbert schrieb: >> Hängt damit zusammen das das 'C' noch als Teil des Hex Wertes angesehen >> wird. > > richtig, aber er sollte eigentlich nur 2 zeichen nach dem \x einlesen. Ich meine gelesen zu haben, das bei '\x...' alles bis zum ersten 'nichtHex' Zeichen beachtet wird. Bei Oktal ist es auf drei Ziffern begrenzt.
Karl Heinz Buchegger schrieb: > fprintf( MUE"C.net" ); Das ist schön und lesbar. Peter II schrieb: > fprintf("\xb5 C.net"); Das erzeugt bei mir ein Leerzeichen zwischen µ und C. Norbert schrieb: > char z[] = "\xb5""C.net" Das probiere ich heute abend auch mal. Hex kriege ich irgendwie besser in den Kopf als Oktal.
Nicolas S. schrieb: > Also war ich bislang davon ausgegangen, > daß ein Compiler/Präprozessor sich die Sachen erstmal wieder in eine > Textebene legt, allein um Leerzeichen, Tabs und Zeilenumbrüche zu > interpretieren. das braucht er keinen zeichensatz weile diese zeichen im ASCII feststehen. Er kann also einfach den den byte-wert vergleichen.
Um zum Kern der Frage zurückzukommen: AVR-Studio verwendet als Unterbau das "Microsoft Visual Studio", das wiederum verwendet im Editor üblicherweise die sogenannte "ANSI"-Codepage (CP1252) - die ist weitestgehend identisch mit ISO 8859-1*. Das ist bei praktisch allen unter Windows arbeitenden Editoren der Standardfall. Neuere Visual-Studio-Varianten (und auch der windowseigene Primitiveditor Notepad) unterstützen jedoch auch UTF-8. Die alten "DOS"-Codepages CP437 bzw. CP850 werden zur allgemeinen Verwirrung aber weiterhin verwendet - in Konsolenfenstern. Das lässt sich umschalten (mode con cp select=1252), bringt aber nur dann befriedigende Ergebnisse, wenn das Konsolfenster nicht mit dem defaultmäßigen Pixelfont betrieben wird -- diese Relikt aus der vorderen Altsteinzeit nämlich legt die Zeichencodierung zusätzlich fest. Dem Compiler ist es weitestgehend wurscht, was er im Quelltext findet - alle Zeichencodierungen haben als Schnittmenge den ASCII-Zeichensatz, und alle für C oder C++ syntaktisch relevanten Zeichen befinden sich in diesem ASCII-Zeichensatz. Wenn in Kommentaren oder Stringkonstanten Zeichen auftauchen, die nicht im ASCII-Zeichensatz liegen (Umlaute etc.), dann kann der Compiler wahlweise Fehlermeldungen ausgeben, oder die im Quelltext vorgefundenen Zeichen so, wie sie sind, durchreichen. Steht da also in einer Stringkonstante etwas, was im verwendeten Texteditor aussieht wie ein µ, dann landet das in exakt derselben Form auch im erzeugten Binärcode. Ob der diesen dann abarbeitende Prozessor die Stringkonstante wiederum in lesbarer Form z.B. auf einem LC-Display ausgibt, hängt vom Zeichensatz des LC-Displays ab -- da beispielsweise HD44780-Displays keine CP1252 verwenden, funktioniert das mit solchen Displays nicht, und eine Umsetzungstabelle ist vonnöten. *) http://de.wikipedia.org/wiki/ISO_8859-1
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.