- SF800 Solar Speicher Tutorial         
Ergebnis 1 bis 10 von 34

Thema: Mein Problem mit den Umlauten

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707

    Cool

    Ich habe jetzt auch noch in mehrere Bücher geschaut und außer "das ist implementierungsabhängig" nicht viel gefunden.

    Meine Vermutung ist, bei
    Code:
    if(wort[i] == 'ä')
    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.)

    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.

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo,
    Zitat Zitat von Mxt Beitrag anzeigen
    Ich habe jetzt auch noch in mehrere Bücher geschaut und außer "das ist implementierungsabhängig" nicht viel gefunden.
    Deshalb gibt es auch Manual zum Compiler.
    Da steht dann in einem Anhang wie das genau ist und welche Parameter was übersteuern.

    Zitat Zitat von Mxt Beitrag anzeigen
    Meine Vermutung ist, bei
    Code:
    if(wort[i] == 'ä')
    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.)
    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)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.698
    .. 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..
    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 wie
    ......typedef uint16_t u16; //typedef unsigned short u16;
    und so

    Danke im Voraus.
    Ciao sagt der JoeamBerg

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Peter, bitte gib dazu ein Beispiel.
    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
    error: character too large for enclosing character literal type
    Es geht nur
    L'ä' (Ausgabe "4 w" im obigen Testprogramm)
    U'ä' (Ausgabe "4 Di")
    u'ä' (Ausgabe "4 Ds")

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo,
    Zitat Zitat von Mxt Beitrag anzeigen
    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 nur
    L'ä' (Ausgabe "4 w" im obigen Testprogramm)
    U'ä' (Ausgabe "4 Di")
    u'ä' (Ausgabe "4 Ds")
    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,
    Zitat Zitat von oberallgeier Beitrag anzeigen
    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 wie
    ......typedef uint16_t u16; //typedef unsigned short u16;
    und so.
    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:
    Code:
    typedef struct
      {
        unsigned char c
        unsigned int i;
      } s_foo;
    Ich gehe mal davon aus, dass char 8-Bit und int 16-Bit haben.

    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).

    Code:
    typedef struct
      {
        unsigned char c
        unsigned int i;
      } s_foo;
    
      s_foo var;
      fwrite(&s_var, sizeof(s_foo), 1, file):
    Scheint jetzt sehr einfach, aber da weiss jetzt keiner was wirklich geschrieben wird.
    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:
    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):
    Wolltest du so etwas?

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Also um die Sache mal von meiner Seite aus abzuschliessen:

    Ich stimme Peter darin zu, dass man für diese Aufgabe mit entsprechenden Bibliotheken besser bedient wäre. Da der Fragesteller mit QtCreator auf dem PC arbeitet, nicht mit einem Mikrocontroller, wären dazu die Datei- und Stringklassen von Qt sicher gut geeignet.

    Die Unicode-Geschichte ist ein typisches Beispiel dafür, dass sich die Mikrocontrollerprogrammierung und die auf den "großen" Betriebssystemen schon etwas unterscheidet. "Einfaches C" kann auf den komplexen Systemen schnell in so einem Minenfeld landen, wie wir es in diesem Thread gesehen haben.

    Was der Fragesteller nicht erwartet hatte, ist das für den GCC etwas in einfachen Anführungszeichen, abhängig vom Inhalt ein char oder int sein kann. Das wusste ich auch nicht. Die anderen C++ Compiler sehen das anders.

  7. #7
    HaWe
    Gast
    Ein typisches Problem für die Portierbarkeit:

    Code:
    typedef struct
      {
        unsigned char c
        unsigned int i;
      } s_foo;
    Ich gehe mal davon aus, dass char 8-Bit und int 16-Bit haben.
    schon wieder lese ich hier was über int und 16 bit und "einfach davon ausgehen".... tstststs...
    das geht hier mit Sicherheit schnell schief!

    auf dem Raspi hat int 32 bits , also int == int32_t
    will man exakt 16 bit int, muss man short verwenden - oder eben int16_t.
    auch word hat hier übrigens 32 bits.

    und char ist auf ARM-Plattformen häufig unsigned char, während es auf AVR Plattformen häufig signed char ist!

    Auch auf dem Arduino Due (ARM Cortex M3) gilt das automatisch !!

    und werden aus einem FILE * stream (Datei als SD-File oder von stdin) Zeichen gelesen, sind es signed int, keine unsigned int, denn es gibt hier auch negative Werte, während der erweiterte ASCII-Zeichensatz (0...255) unsigned char ist !!


    Mein Tipp:
    vergesst doch einfach mal die alten Datentypen.

    per gpp und Arduino sind die C11-Datentypen bereits implementiert,
    bei gpp für Raspi muss man bei Raspbian per Hand includen:
    #include <stdint.h>

    dann weiss man, was man hat.


    ps,
    für Buchstaben gibt es bei Raspi C++ auch den Datentyp
    wchar_t
    mit 8-16 bit, der alle "chars" aufnimmt, seien es uint8_t oder int16_t.

    Datentyp wchar_t
    Der Datentyp char ist nicht in der Lage, die Zeichensätze aller nationaler Sprachen zu repräsentieren. Um zum Beispiel auch mit dem japanischen Zeichensatz umgehen zu können, ist dieser Datentyp "zu klein".

    Die Darstellung beliebiger landesspezifischer Zeichensatze kann mit Hilfe des Datentyps wchar_t (wide characters) vorgenommen werden, der mit ANSI-C eingeführt wurde.
    Die Definition des Datentyps erfolgt in der Header-Datei stddef.h.

    wchar_t ist ebenso wie char, int, ... ein integraler Datentyp.

    Literale vom Typ wchar_t besitzen folgende Gestalt

    L'..'

    http://www2.informatik.uni-halle.de/...c/c_wchar.html
    s.a. http://www.raspberry-projects.com/pi...mory/variables

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Zitat Zitat von HaWe Beitrag anzeigen
    schon wieder lese ich hier was über int und 16 bit und "einfach davon ausgehen".... tstststs...

    Mein Tipp:
    vergesst doch einfach mal die alten Datentypen.

    #include <stdint.h>

    dann weiss man, was man hat.
    +1


    wchar_t ist der native Typ des Betriebssystems für wide characters. Unter Windows sind das 2 Byte, unter Linux 4, wie oben in den Ausgaben gezeigt. (Schreibweise L"...").

    Dann gibt es in neuerem C++ noch char32_t, Schreibweise U"...", sollten eigentlich überall 4 Bytes sein.

    Mit kleinem u"..." ist es eigentlich char16_t, wie wir oben gesehen haben unter Linux trotzdem 4 Bytes, unter Windows sind es 2.

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo,
    Zitat Zitat von HaWe Beitrag anzeigen
    schon wieder lese ich hier was über int und 16 bit und "einfach davon ausgehen".... tstststs...
    das geht hier mit Sicherheit schnell schief!
    Manche hier haben verstanden, was ich geschrieben habe, andere haben den Satz aus den Zusammenhang gerissen!

    Ich kenne auch noch CPUs bei denen char 9-Bit hat!
    Bei K&R, stand schon in der ersten Ausgabe:
    Garantiert ist nur, dass "char <= int <= Long" ist. char kann dabei aber auch 38-Bit haben.

    MfG Peter(TOO)

    - - - Aktualisiert - - -

    @Geier,

    Das war nur etwas Tipparbeit.

    MfG Peter(TOO)
    Geändert von Peter(TOO) (07.02.2016 um 20:30 Uhr)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  10. #10
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.698
    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    . . . Wolltest du so etwas? . . .
    Peter, vielen Dank, genau das bringt mich weiter. Danke für die viele Mühe.
    Ciao sagt der JoeamBerg

Ähnliche Themen

  1. Mein I2C Logger-Problem
    Von oberallgeier im Forum AVR Hardwarethemen
    Antworten: 10
    Letzter Beitrag: 25.11.2010, 16:18
  2. Wer hat eine Lösung für mein Schaltungs-Problem?
    Von Grillmeister Markus im Forum Elektronik
    Antworten: 15
    Letzter Beitrag: 18.08.2006, 12:50
  3. Mein RP2 !
    Von Chefkoch im Forum Vorstellungen+Bilder von fertigen Projekten/Bots
    Antworten: 30
    Letzter Beitrag: 09.08.2005, 15:33
  4. mein 2. bot...
    Von Bluesmash im Forum Vorstellung+Bilder+Ideen zu geplanten eigenen Projekten/Bots
    Antworten: 6
    Letzter Beitrag: 04.07.2005, 16:12
  5. Mein RP5
    Von OrpheusOne im Forum Robby CCRP5
    Antworten: 21
    Letzter Beitrag: 27.08.2004, 20:42

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests