Da bekomme ich
zurück...Code:Fehler: 'c' does not name a type
auto c = 'ä';
^
Druckbare Version
Da bekomme ich
zurück...Code:Fehler: 'c' does not name a type
auto c = 'ä';
^
Spannend.
Visual Studio 2015 hat ja zwei C++ Compiler. Wenn ich
mit Clang übersetze, produziert das 'ä' auch eine Warnung.Code:auto c = 'ä';
das ^ welches die Fehlerposition markiert, steht beim ersten 'Zitat:
warning : illegal character encoding in character literal [-Winvalid-source-encoding]
auto c = '<E4>';
Kombiniere, das 'ä' ist anscheinend nicht überall erlaubt und tut nicht was du meinst. Das muss ich auch mal weiter erforschen. Da ist mir was bisher entgangen.
- - - Aktualisiert - - -
=======
Ok,
die Meldung " 'c' does not name a type " kommt wohl eher daher, dass kein C++11 oder 14 eingeschaltet ist und hat somit nicht direkt mit dem Problem zu tun.
Ansonsten wollen g++ oder clang wohl lieber Unicode Quelltextdateien, wenn du da mit Umlauten in Literalen arbeiten willst. Ob einzelne oder doppelte Anführungszeichen macht wohl keinen Unterschied.
Dann nehm für deinen Vergleich halt das ä als Hexkonstante, so in der Art
oder was immer der Code des Zeichens bei dir ist.Code:const char c = 0xe4;
Ich bekomme
zurückCode:1 c
Das ist ok, der g++ ist bei typeid wohl nicht so ausführlich.
Aber dann ist c ein Byte groß und kann daher nicht 50000 sein, schau mal mit dem Debugger hinein.
Funktioniert es, wenn du das ä wie oben durch eine Konstante ersetzt ?
===
Nachtrag: Auf dem Raspi mit Raspian und vim als Editor ist die Ausgabe tatsächlich
4 i
das 'ä' wird dort also 4 Byte groß. Ein "file -bi dateiname" zeigt, dass die Datei als utf-8 gespeichert wird.
wenn ich mich nicht irre, liest die C-read (scan, getc oder C++ << -) Funktion von stdin nicht einen unsigned char sondern ein int16_t. Man liest ja aus einem FILE * stream und da wird auch grundsätzlich bei eof() eine -1 zurückgegeben (erinnere mich dunkel an so etwas), also kann es kein uchar sein. Die Codierung deutscher Umlaute und Sonderzeichen jenseits ASCII 127 ist dennoch ungewiss.
Ich habe jetzt auch noch in mehrere Bücher geschaut und außer "das ist implementierungsabhängig" nicht viel gefunden.
Meine Vermutung ist, bei
betrachtet der g++ die rechte Seite des Vergleichs als int, also wahrscheinlich einen etwas größeren Zahlenwert (228 ?). Wenn wort ein char Array ist, werden die Werte auf der linken Seite vor dem Vergleich nach int umgewandelt, da kommen dann nur Werte von -126 bis 127 raus, der Vergleich schlägt also immer fehl. (Da holt man sich auch noch wieder das Problem rein, dass auf ARM ein char vorzeichlos ist und auf Intel eines hat.)Code:if(wort[i] == 'ä')
Wenn ich meinen Raspi wieder mal auf Arch Linux umgesteckt habe, muss ich das mal mit einem aktuellen g++ 5.3.x vergleichen.
Wahrscheinlich ist man mit den Präfixvarianten für Stringkonstanten sicherer, also L"text", U"text" oder u"text", dann hat man aber immer Unicode in verschiedenen Varianten.
Sonst halt Zahlenkonstanten statt Zeichen, oder eben in Konsolenanwendungen immer englisch schreiben.
Hallo,
Deshalb gibt es auch Manual zum Compiler.
Da steht dann in einem Anhang wie das genau ist und welche Parameter was übersteuern.
Da ist halt wieder die Frage, wie char implementiert ist.
Wenn man sicher gehen will, verwendet man char gar nicht!
Sondern explizit unsigned char und signed char.
Ich habe in meinen Programmen vor 30 Jahren ein typedef für uchar und schar verwendet, dann muss ich nicht so viel tippen und es funktioniert mit jedem Compiler. :-)
Mit ANSI-C wurden dann typen wie int8_t und uint8_t eingeführt, welche bei jeder Implementierung gleich sind, eingeführt.
Bibliotheken, welche mit unterschiedlichen Text-Codierungen zurecht kommen, haben meistens eigenen Datentypen, welche an Stelle von char verwendet werden sollten.
Ich habe viel Code geschrieben, welcher meistens auf PC und µC laufen musste (Vor allen Übertragungsprotokolle). Da kommt dann noch das Problem von Little und Big Endian hinzu. Aber wenn man ein paar Dinge berücksichtigt, geht das ganz gut und auch ganz ohne den Code doppelt zu schreiben und mit #if nur Teile zu Compilieren.
MfG Peter(TOO)
Peter, bitte gib dazu ein Beispiel. Denn ich bin a) reichlich unwissend und b) stehen solche fortgeschrittenen Beispiel ja leider (soweit ich es bisher sah) nicht im Manual. Und bisher stehen in meinem Definitions-Faulenzer (mydefs.h) nur Dinge wieZitat:
.. Deshalb gibt es auch Manual zum Compiler .. Wenn man sicher gehen will . . Sondern explizit unsigned char und signed char.
Ich habe in meinen Programmen vor 30 Jahren ein typedef für uchar und schar verwendet, dann muss ich nicht so viel tippen und es funktioniert mit jedem Compiler..
......typedef uint16_t u16; //typedef unsigned short u16;
und so
Danke im Voraus.
Ja, insbesondere zur Verwendung von Eingabefunktionen wie getch usw., da ist man ja auf deren Rückgabewert und dessen Typ angewiesen, wie HaWe richtig angemerkt hat.
Außerdem dürfte es in der g++ Doku nicht so einfach nachzulesen sein, warum der bei dem auto Testbeispiel oben, wenn er also template type deduction verwendet, beim Fragesteller sagt das 'ä' sei 1 Byte groß, in dem if dagegen die "multi byte constant" dann implizit als int betrachtet. Ich bin noch dabei zu erforschen, ob sich da verschiedene g++ unterschiedlich verhalten, und ob es Unterschiede zu clang++ gibt.
- - - Aktualisiert - - -
==
So, Neuigkeiten.
Auf dem Raspi mit Arch mit g++ 5.3.0 das gleiche Bild wie mit Raspian.
Aber mit dem clang 3.7.1 und -std=c++14 wird ein 'ä' gar nicht mehr übersetzt. Das gibt jetzt ein
Es geht nurZitat:
error: character too large for enclosing character literal type
L'ä' (Ausgabe "4 w" im obigen Testprogramm)
U'ä' (Ausgabe "4 Di")
u'ä' (Ausgabe "4 Ds")
Hallo,
Die Frage ist jetzt was es werden soll?
Eine Lösung ist, dass du einen Text-Editor nimmst, der reinen ASCII-Text erzeugt, bzw. deinen entsprechend einstellst (Kann schon am gewählten Zeichensatz liegen).
Du erzeugst mit dem Editor ein Textfile welches den Vorgaben des Betriebssystems folgt.
Nun hat aber dieses Betriebssystem oft gar nichts mit dem zu tun, was auf deinem µC vorhanden ist.
Die Motzerei des Compilers bezieht sich auf die Textdatei, welchem ihm gefüttert wird.
Die andere Möglichkeit ist, den Compiler so einzustellen, dass er mit Mehrbyte-Zeichen zurecht kommt, dann muss dies aber auch von der Laufzeitumgebung des µC unterstützt werden.
MfG Peter(TOO)
- - - Aktualisiert - - -
Hallo Geier,
Was für Beispiele willst du jetzt?
Bei mir stand da halt
typedef unsigned char uchar
Meinen Faulenzer hatte ich mit GoeDef.h bezeichnet.
Ein typisches Problem für die Portierbarkeit:
Ich gehe mal davon aus, dass char 8-Bit und int 16-Bit haben.Code:typedef struct
{
unsigned char c
unsigned int i;
} s_foo;
Manche CPUs können 16-Bit-Zugriffe nur auf gerade Adressen machen, weshalb der Compiler zwischen c und i noch ein Füllbyte einfügen muss. Kann man beim Compiler unter Alignement beeinflussen. Manche CPUs können auch auf ungeraden Adressen 16-Bit Zugriffe machen, brauchen dann aber 2 Speicherzyklen. Hier kann dann die Optimierung auf Geschwindigkeit das Füllbyte erzwingen.
Und bei int weiss man nicht ob da zuerst das Low-Byte oder das Hight-Byte abgelegt wird. Bei 32-Bit gibt's dann schon 4 Möglichkeiten (Endian).
Scheint jetzt sehr einfach, aber da weiss jetzt keiner was wirklich geschrieben wird.Code:typedef struct
{
unsigned char c
unsigned int i;
} s_foo;
s_foo var;
fwrite(&s_var, sizeof(s_foo), 1, file):
Je nach Füllbyte sind es 3 oder 4 Byte und wie der int dargestellt wird, weiss man auch nicht.
Eine sauber Lösung ist:
Wolltest du so etwas?Code:typedef struct
{
unsigned char c
unsigned int i;
} s_foo;
s_foo var;
unigned char buf[3];
buf[0] = var.c;
buf[1] = (var.c >> 8) & 0xFF;
buf[2] = (var.c ) & 0xFF;
fwrite(buf, sizeof(buf), 1, file):
MfG Peter(TOO)