wxWidgets - Textdatei(UTF-8) zeilenweise einlesen



  • Hallo zusammen!

    Wie der Titel schon sagt möchte ich eine Textdatei zeilenweise auslesen. Bisheriger Ansatz:

    #include <fstream>
    #include <string>
    
    void ReadFile()
    {
        std::ifstream FILE;
        std::string LINE;
    
        FILE.open("Textdatei.txt");
    
        while (!FILE.eof())
        {
            getline(FILE, LINE);
    
            //tue etwas mit der jeweils in den String LINE eingelesenen Zeile
        }
    
        FILE.close();
    }
    

    Nun ist die Textdatei aber UTF-8 kodiert und enthält z.B Buchstaben des kyrillischen Alphabets. Diese Zeichen können offenbar nicht in einen std::string geschrieben werden.

    Meine Nachforschungen haben ergeben dass es in wxWidgets die Klasse wxTextfile gibt und dass wxString, anders als std::string, auch UTF-8 Codierung akzeptiert.

    Wie müsste das obige Beispiel aussehen damit die Zeilen der Textdatei gleich in einen wxString (und nicht wie im Beispiel in einen std::string) eingelesen werden?

    Schonmal vielen Dank im Voraus!



  • Das hier muesste gehen (ungetestet):

    void ReadFile()
    {
        wxTextFile FILE;
        wxString LINE;
    
        FILE.Open("Textdatei.txt");
    
        for (LINE = FILE.GetFirstLine(); FILE.Eof() == false; LINE = FILE.GetNextLine())
    	{
            //tue etwas mit der jeweils in den String LINE eingelesenen Zeile
        }
    }
    


  • Mach dich noch mal Schlau, was UTF-8 bedeuted !

    Und gleich vorneweg, std::string kann einen UTF-8 String transportieren.
    UTF-8 ist ASCII "kompatibel" (auf 8 bit systemen, 7 bit Systeme koennen kein Utf-8 klar ^^), es ist in erster Linie eine Darstellungfrage.
    Du musst also Quasi der Darstellenden Schicht nur "sagen" das es UTF-8 ist, und nicht "nur" ASCII .

    wxString selber kann 8bit / 16 bit / 32 bit breite Zeichen haben. Je nach Plattform (wchar_t 16 oder 32 bit) / Compilereinstellungen (wxstring nutzt char oder wchar_t).
    Also wirst dich auf Plattformeinheitliche Einstellungen verlassen muessen.
    Das WXWidgets nen wxString als utf codiert betrachen, musst du ueber ne compiler direktive festlegen. das heisst er kann dann nur utf-8 (keine Ahnung ob das per default an ist) ... was aber füer ASCII keinen unterschied macht (kompatiblitaet)

    Wenn also komplett wx Klassen verwendest, bist da scho mal auf der sicheren seite.
    statt fstreams, also wxfile verwenden, siehe wxwidget Doku .

    wenn das UTF-8 angeschaltet ist, interpretiert er auch std::string als utf-8 ... und spatestens in den wxWidget funktionen, die irgendwie auf die gui was schieben, wird er den standard string in nen wxString umwandeln ...
    Also macht da wxString und std::string kein unterschied ...

    Ciao ...



  • Vielen Dank, funktioniert erstmal!
    Ich habe mein Programm jetzt so umgeschrieben dass nur noch wxStrings verwendet werden in der Hoffnung jetzt auch Zeichen z.B. aus dem russischen Alphabet verarbeiten zu können. Leider werden diese Zeichen immer noch nicht erkannt und an ihrer statt wird ein '?' ausgegeben. 😞
    Es muss doch irgendwie möglich sein ein UTF-8 codiertes Textfile einzulesen und auch die nicht-ANSI-Zeichen zu verarbeiten... 😕

    EDIT: Antwort zu spät gelesen



  • Als einfachstes Beispiel möchte ich versuchen aus einer Textdatei die Zeile

    Ваня

    in einen wxString einzulesen und dann in ein wxTextCtrl::Textfeld mittels

    Textfeld->SetValue(LINE);
    

    auszugeben.
    Aber wie schon oben geschrieben erscheinen im Textfeld nur vier Fragezeichen.
    Leider habe ich keine Ahnung wie ich dem Compiler mitteilen kann dass er alle eingelesenen Zeichen als UTF-8 codierte Zeichen behandeln soll.



  • kenn mich mit wxWidgets ned soo aus.
    aber :

    The UTF-8 build will be identified by defining wxUSE_UNICODE_UTF8 macro.

    das mal in deine Präprozesserdefinitionen einfügen und noch mal schauen .

    Keine Ahnung ob man wxWidgets für Utf-8 neu übersetzen muesst. glaub aber eher nicht ^^

    Den std::string dann mal vorsätzlich in nen wxString umwandeln, falls der intern fuer wxString Unicodes verwendet ...

    #include <fstream>
    #include <string>
    
    void ReadFile()
    {
        std::ifstream FILE;
        std::string LINE;
    
        FILE.open("Textdatei.txt");
    
        while (!FILE.eof())
        {
            getline(FILE, LINE);
    
            wxString wstrLine = wxString::fromUTF8(Line.c_str());
            //tue etwas mit der jeweils in den String strLINE eingelesenen Zeile
            // schicke den wstrLine an wxWidgets und hoffe die können utf-8 darstellen ! 
    
        }
    
        FILE.close();
    }
    

    Übrigens, glaub nicht das console Ausgaben utf-8 faehig sind. Also solltest das teil schon an nen GUI Object schicken ....

    utf-8 auf console geht auch, ist aber "relativ unstaendlich" unter windows ...
    Linux sollte es mit bestimmten einstellungen nativ supporten

    Ciao ...



  • Die Zeichen muessten eigentlich richtig dargestellt werden.
    Wahrscheinlich verwendest du ein falsches Build.

    Keine Ahnung ob man wxWidgets für Utf-8 neu übersetzen muesst. glaub aber eher nicht ^^

    doch, muss man,.

    @Threadstarter
    Pruefe am besten nach ob "wxUSE_UNICODE" (ohne das _UTF8) definiert ist, um generall mal zu pruefen, ob du ueberhaupt ein Unicode-Build verwendest. Wenn nicht, hast du ein ANSI-Build und du musst wxWidgets neu kompilieren/installieren.

    wxString wstrLine = wxString::fromUTF8(Line.c_str());
    

    Voelliger Kaese 🙂
    wxTextFile liest die Datei automatisch in der richtigen Kodierung, sodass man sich NICHT darum kuemmern muss.



  • Vielen Dank für die Antworten!

    wxUniversal schrieb:

    Pruefe am besten nach ob "wxUSE_UNICODE" (ohne das _UTF8) definiert ist, um generall mal zu pruefen, ob du ueberhaupt ein Unicode-Build verwendest. Wenn nicht, hast du ein ANSI-Build und du musst wxWidgets neu kompilieren/installieren.

    Wo und wie kann ich das überprüfen?
    Ich habe mir recht unbedarft den Installer wxdevcpp_7.3.1_full_setup.exe heruntergeladen und installiert, ob dabei noch irgendwelche Installations-Parameter abgefragt wurden weiß ich nicht mehr.
    Werds mal neu installieren und schauen was passiert...



  • Das koenntest du z.B. so pruefen:

    #ifdef wxUSE_UNICODE
    wxMessageBox("unicode");
    #endif

    Ich kenne den Installer nicht. Anscheinend ist es aber ein Plugin fuer die veraltete, fehleranfaellige IDE DEV++
    Nimm lieber den Microsoft Visual C++ 2010 Express und dann am besten gleich die neue wxWidgets Version 2.9.



  • Ich hab noch mal ein bischen geforscht: Der auf der wxWidgets-Homepage angebotene Installer ist kein Unicode-Build.
    Die Frage ist jetzt: Wo bekomme ich einen (aktuellen) wxWidgets Unicode-Build her?
    Hat da jemand nen Tip für mich?

    Alternativansatz (bisher erfolglos):

    Statt wxString die Klasse wxUString verwenden: wxUString Class Reference

    Mit dem header #include <wx/ustring.h> bekomme ich eine Menge Fehler beim Compilieren die ich nicht verstehe. Diese Fehler treten in der defs.h , textfile.h und der platform.h auf.



  • Ok, zugegeben, ich komm mir grad ganz schön blöd vor... 😕

    Wie schon gesagt habe ich bisher einen full-installer zur Installation verwendet. Dieser ist aber wohl veraltet und so möchte ich jetzt "ganz aktuell" einsteigen mit wxWidgets-2.9.2

    Download: http://www.wxwidgets.org/downloads/

    Hier habe ich den Windows Installer wxMSW-2.9.2-Setup.exe runtergeladen und ausgeführt (und damit entpackt).

    Anschliessend habe ich Visual Studio 2010 Express installiert.

    Ich folge dieser Video-Anleitung: http://www.e-socrates.org/mod/page/view.php?id=1570
    (Ist für Visual Studio Express 2008 und wxWidgets 2.8.8 ...)

    Problem: Die Konvertierung des wxWidgets-Projekts (die statische Variante) für Visual Studio 2010 Express schlägt fehl, die Projektdateien werden nicht geladen.

    Tut mir Leid wenns ne echt doofe Frage ist, aber ich bräuchte da wirklich ein bischen Hilfe...



  • Hallo.

    2.9.2 ist eine gute Wahl. Ich benutz schon seit Monaten die "2.9-Reihe" und hatte noch nie Probleme damit (will sagen, die laeuft aeusserst stabil).
    Die String-Klasse in 2.9 wurde komplett ueberarbeitet und unterstuetzt ab sofort Unicode von "Haus aus" (ANSI-Builds gibt es nicht mehr, soweit ich weiss). Ausserdem muss man jetzt das nervige "wxT()"-Makro nicht mehr benutzen 🙂

    Zugegeben, es ist etwas schwierig es fuer MSVC 2010 zu installieren, aber du wirst es nicht bereuen. 😉
    Der Installer bietet keine direkte Visual C++ 2010 Unterstuetzung (nur bis 2008, warum auch immer...), deshalb musst du dir die Projektdatei extra herunterladen.
    Hier ist eine genaue Anleitung:
    http://wiki.wxwidgets.org/Microsoft_Visual_C%2B%2B_Guide#Visual_Studio_C.2B.2B_2010

    Die Anleitung hab ich selber benutzt (zwar nur fuer 2.9.1 - weil ich bisher zu faul war 2.9.2 zu installieren, aber muesste eigentlich genausogut klappen...).

    Hier die Schritte wie ich es gemacht hab:

    - Lade dir die Datei "wx291_msw_vc10.zip" (zweiter Beitrag) von hier runter.

    - Entpacke den Ordner in <wxWidgets Order>/build

    - Oeffne "wx_vc10.sln". Wenn du die C++ Laufzeit Bibliotheken von MS statisch kompilieren willst, musst du die Laufzeitbibliothek aller Projekte auf "Multithreaded" bzw. "Multithreaded-Debug" (im Debug-Modus) aendern (ansonsten muesste dein User sonst die 2010 Redistributable installieren).
    Es ist eigentlich ganz einfach (auch wenns laenger dauert...): Gehe links alle Projekte durch von oben bis unten, angefangen bei "adv": Rechte Maustaste druecken und "Eigenschaften" waehlen. Unter "Konfigurationseigenschaften"/"C/C++"/"Codegenerierung" findest du dann rechts "Laufzeitbibliothek". Dort z.B. "Multithreaded-Debug-DLL" auf "Multithreaded-Debug" aendern bzw. "Multithreaded-DLL" auf "Multithreaded" aendern.
    Das ganze machst du fuer jedes Build, dass du verwenden willst (wahrscheinlich nur "Debug" und "Release" (vielleicht noch "Universal Release"/"Universal Debug").
    Irgendein Build geht uebrigens nicht, es war eins der DLL-Builds fuer den Universal-Port (wird sowieso uninteressant fuer dich sein).

    - Nachdem das erledigt ist, geh im Menue ganz oben auf "Erstellen"/"Batch erstellen". Dann auf den Button "alle auswaehlen" klicken. Jetzt musst du nur noch ueberallden Haken entfernen, was du nicht kompilieren moechtest (z.B. ein Haken fuer den "DLL Debug|Win32"-Build). Dann kannst du auf "erstellen" klicken.

    - Abwarten. Der Kompilierungsvorgang kann je nach PC ziemlich lange dauern...

    - Nach dem Kompilieren muessten - wenn ich mich nicht irre - die Lib-Dateien schon im Ordner "<wxWidgets-Ordner>/lib/vc_lib" sein.

    Wenn du jetzt ein eigenes Projekt erstellst, musst du in den Konfigurationseigenschaften unter "C/C++"/Allgemein bei "Zusaetzliche Includeverzeichnisse" die Ordner
    <wxWidgets Ordner>/include
    und
    <wxWidgets Ordner>/include/msvc
    miteinbinden (Hinweis: Der "C/C++"-Bereich in den Eigenschaften wird erst sichtbar sobald du eine cpp-Datei in deinem Projekt hast)
    Unter "Linker"/Allgemein bei "Zusaetzliche Bibliotheksverzeichnisse" den Ordner
    <wxWidgets Ordner>/lib/vc_lib
    einfuegen
    Und dan unter "Linker"/Eingabe die ganzen Bibliotheken einfuegen, die du verwenden willst. Bei mir sind das im Debug-Modus meistens:

    wxbase29ud.lib
    wxmsw29ud_core.lib
    wxjpegd.lib
    wxpngd.lib
    wxtiffd.lib
    wxzlib.lib
    

    und im Release-Modus:

    wxbase29u.lib
    wxmsw29u_core.lib
    wxjpeg.lib
    wxpng.lib
    wxtiff.lib
    wxzlib.lib
    

    Dann kannst du dein Projekt kompilieren und starten (z.B. im Debug-Modus mit "F5").

    Hoffe, es klappt. 🙂



  • Vielen Dank für die ausführliche Anleitung!
    Ich bin übers Wochenende bei meiner Familie zu Besuch, deshalb werd ichs erst die nächste Woche ausprobieren können. Melde mich dann wieder und berichte obs hingehauen hat.
    Danke für die Hilfe, Alberich



  • Muss mich etwas korrigieren.

    Hab jetzt selbst die 2.9.2 kompiliert, um mal endlich auf den neusten Stand zu sein.
    Die Projektdatei, die ich im obigen Beitrag verlinkt habe funktioniert nicht mehr mit 2.9.2 (8 Projekte kompilieren nicht).
    Stattdessen aber mit der "wx_vc7.sln", die bereits im wxWidgets Ordner (build/msw) vorhanden ist. Projekt einfach von Microsoft Visual C++ 2010 konvertieren lassen (es gibt zwar einige Warnungen beim konvertieren, die kann man aber ignorieren) und einfach die obigen Schritte ausfuehren. Beim kompilieren gibt es zwar einige Warnungen, die kann man aber unbesorgt ignorieren (die entstehen nur deswegen, weil zwei unterschiedliche Pfade in der Projektdatei vorhanden sind: einer relativ und der andere absolut).
    Auf diese Loesung bin ich durch diesen Thread gekommen:
    http://forums.wxwidgets.org/viewtopic.php?f=19&t=30531&p=130983
    Damit kompilieren alle Projekte einwandfrei.



  • OK, ich bin deiner Anleitung Schritt für Schritt gefolgt und habe wxWidgets erfolgreich kompilieren können (wx_vc7.sln).
    Um zu überprüfen ob alles funktioniert wollte ich dann eines der vielen Beispiele kompilieren, in diesem Fall "minimal.cpp". Dort gibt es verschiedene Auswahlmöglichkeiten, unter anderem:

    minimal_vc7.vcproj
    minimal_vc7.vcxproj

    Beide Projektdateien können konvertiert werden, das Erstellen schlägt aber leider mit der Fehlermeldung "Fehler beim Erstellen. Möchten Sie den Vorgang fortsetzen und den letzten erfolgreichen Build ausführen?" fehl. Da dieser nicht existiert kommt dann gleich nach "Ja" die zweite Fehlermeldung dass die .exe nicht gefunden wurde.

    Was könnte da schiefgegangen sein?



  • Du musst in den Konfigurationseigenschaften unter "C/C++"/"Codegenerierung" die Laufzeitbibliothek von "Multithreaded-Debug-DLL" zu "Multithreaded-Debug" aendern (bzw. im Release-Modus von "Multithreaded-DLL" zu "Multithreaded").
    Dann klappt es 🙂



  • Ahhh... das hatte ich nicht bedacht!
    Vielen Dank, jetzt wird das Beispiel fehlerfrei kompiliert.

    Nu is erstmal umgewöhnen an die neue Umgebung angesagt. 🙂

    Ich habe bisher die (veraltete) Umgebung wxDevC++ verwendet und hier gab es einen recht bequemen Editor (*.wxform) in dem man die GUI flott zusammenklicken konnte.
    Etwas ähnliches bietet nun auch das Visual Studio (Windows Formbuilder), aber gibt es nicht auch einen solchen Formbuilder für wxWidgets-Steuerelemente?
    Ich bin gerade dabei mich in die Sache einzulesen, aber vielleicht hat ja doch jemand ne flotte Antwort für Dummies parat. 🙂

    Vielen Dank für die Unterstützung bisher!



  • Kein Problem.
    Visual C++ 2010 Express ist wahrscheinlich im Moment die beste und maechtigste kostenlose IDE, die es gibt.
    Besonders klasse find ich die Syntaxpruefung waehrend des Tippens (fehlerhafter Code wird dann so rot unterstrichen wie bei den Rechtschreibpruefungen). Damit lassen sich bereits schon viele Fehler noch vor dem Kompilieren beseitigen.
    Und der Debugger ist auch wirklich unschlagbar, das wirste aber schon selber bald merken 🙂
    Und zwischen dem erstklassigen Visual C++ Compiler und dem MinGW-Compiler liegen Welten.

    Der Form Builder in Visual C++ funktioniert in der Express-Edition gar nicht, soweit ich weiss. Abgesehen davon ist der nur fuer .net-Anwendungen glaub ich.

    GUI Designer fuer wxWidgets gibts wirklich viele, einige davon nur als Plug-In fuer IDEs, z.B. wxSmith fuer CodeBlocks. Es gibt aber auch viele Standalone Designer, wie z.B. wxGlade oder wxFormBuilder (naja, das sind auc schon alle, die ich kenne 😃 )
    Ich selber benutze aber keine GUI Designer (ich kommte mit Sizern sehr gut klar), deswegen kann ich dir da keinen empfehlen.
    MAch am besten einen neuen Thread auf, wenn dich das Thema interessiert, da hier wohl nur noch die wenigsten reinschauen..


Log in to reply