Multi language auswahl für programm



  • Du wirst um Textdateien wohl nicht rumkommen, wenn du nicht
    über Stringtables in den Resourcen es jeweils laden willst.

    Am besten machst du dir eine Zentrale Klasse die am Anfang
    die Strings läd und dann verteilt.



  • lol...das macht man doch nicht bei nem Webserver 👎



  • @webserfer

    warum nicht nur weil der standart webserver apache mit schlechtem beispiel vorrangeht und alles nur in englisch anbietet?

    bei meinen ist ja nochmehr drin z.b. ein forum und ein ordentliches webinterface und ich möchte eben das der user wenn er möchte den webserver in deutsch haben kann
    betrifft auch fehlermeldungen und den dynamischen index

    @phlox81 kannst du das mit der klasse noch ein wenig besser beschreiben



  • Auch wenns locker 300 Texte sind kann man das locker machen.
    Zum Beispiel getrente Dateien für verschiedene Bereiche wie Menu, Fehlermeldungen,
    Buttontexte u.s.w.

    Hier mal ein auszug wie das bei DevCpp gelöst ist (wirklich nur ein kleiner Ausschnitt)

    [lang]
    Lang=German (Deutsch)
    Ver=1

    #Top level menus
    100=&Datei
    101=B&earbeiten
    102=&Suchen
    103=&Ansicht
    104=&Projekt
    105=Ausführ&en
    106=&Werkzeuge
    107=&Fenster
    108=&Hilfe
    109=&Fehlersuche

    #File menu
    120=&Neu
    121=&Projekt...
    122=&Quelldatei
    123=&Ressourcen Datei
    124=&Vorlage...

    130=Pr&ojekt oder Datei öffnen...
    131=&Neu öffnen
    132=Ges&chichte löschen
    133=&Speichern
    134=Speichern &unter...
    135=&Alles Speichern
    136=S&chließen
    137=Projekt schließen
    138=Eigenschaften
    139=Speichere Projekt als...

    Verschiedene Bereiche fangen mit einer groszügig gewählten Indexnummer an damit das ganze erweiterbar bleibt.



  • Also ich würde mal sagen, XML ist geradezu prädestiniert dafür.

    <?xml version="1.0"?>
    <messages>
        <message xml:lang="de" id="bla">Bla</message>
        <message xml:lang="en" id="bla">Foo</message>
    </messages>
    

    oder

    <?xml version="1.0"?>
    <!-- Datei deutsch.xml -->
    <messages xml:lang="de">
        <message id="bla">Bla</message>
    </messages>
    
    <?xml version="1.0"?>
    <!-- Datei englisch.xml -->
    <messages xml:lang="en">
        <message id="bla">Foo</message>
    </messages>
    

    Nun lässt du die Dinger irgendwie parsen, sodass sie dauerhaft verfügbar sind (am besten nur in einer Sprache) und baust dir eine Klasse Message oder so ähnlich, für die du den Input/Output Krams überlädst.

    cout << message ("bla");
    webinterface << message ("bla");
    


  • hätt dazu mal 2 fragen

    erstens was ist der vorteil von den xml basierten lösung oder anders gefragt wann sollte man xml der normalen textversion vorziehen

    und zweitens mein problem bei der textbasierten variante ist die zuweisung in den strings

    mein bisheriger ansatz

    datei zeilenweise einlesen
    jede zeileparsen
    und kontrollieren ob der erste teil mit ner variable übereinstimmt wenn ja wird der 2teil der variable als wert zugewiesen mein problem pro textzeile fallen so 4zeilen code an

    und glaube das wäre ein bißchen viel



  • Wenn du Klasse/n geschrieben hast, die Messages ausgeben und verwalten dann hast Du nur eine Zeile im Aufruf (ein faules Copy&Paste aus einem aelteren Project von mir - sollte nur Fehler, Warnings und Logs schreiben):

    class ErrorMssg
    {
     private:
    
    	FILE			*pError,
    				*pWarning,
    				*pLog;
    
    	char			*szErrorFilename,
    				*szWarningFilename,
    				*szLogFilename,
    
                                    *szStringTable;
    
            StringList              *pStringTable;
    
     public:
    
    // Konstructor tut hier wenig zur Sache, zu speziell, liest aber u.a. 
    // aus dem Filenamen die StringTable ein
    
    	bool Write	(const char    *szMssg,
    			 short	    	iTypeNo);
    
            bool Write (int     iError_No0,
                        int     iError_No1,
                        short   iTypeNo);
    
    // usw.
    
            static short GetCodeLog (void);
    }
    
    #define WRITE_IN_LOG    ErrorMssg::GetCodeLog ();
    

    StringList ist eine Liste von Strings, die aus dem File StringTable gelesen wird. Ich konnte damit eine Errormessage in beliebigen Sprache durch Austausch des Stringfiles auslesen - mit einem Aufruf:

    Also irgentwo anders:

    bool AndereKlasse::MacheWas (ErrorMssg    *pError)
    {
    
    //irgentwas
    
        pError->Write (12, 10, WRITE_IN_LOG);
    }
    


  • Kein Mensch würde doch in der Praxis alle Textzeilen "manuell" einzeln untereinander in den Code schreiben. Wozu gibts schleifen??



  • kann mir da vielleicht noch jemand weiterhelfen sehe da nicht wirklich durch

    das mit stringtable bringt mich auch nicht weiter finde zwar immer sachen wie das im programm selbst gemacht wird aber es gab keine informationen wie man den inhalt der stringtables dynmisch aus ner textdatei lädt auch bei google hat ne suche na stringtable mich nicht weiter gebracht

    danke schonmal stehe da leider irgendwie auf den schlauch



  • so hier mal meine ein wenig zusammengeschusterte funktion

    dazu hab ich dann mal ein paar fragen:

    -kann dies noch hinsichtlich der sicherheit optimiert werden?
    - gibt es noch irgendwelche funktionen die bezüglich der aufgabe multi language support sinnvoll währen und ich daher implementieren sollte/könnte?

    [cpp]#ifndef __LANGUAGE_H__
    #define __LANGUAGE_H__

    #include <map>
    #include <iostream>
    #include <string>
    #include <cctype>
    #include <fstream>
    #include <sstream>

    using namespace std; // Use the standard namespace

    language.h

    // Map von Languahe Strings
    typedef std::mapstd::string,std::string language_str;

    void readinlanguage(char *LanguageFile);

    #endif

    [/cpp]

    language.cpp

    void readinlanguage(char *LanguageFile)
    {
    
          char LangFile[255];
          language_str lang_str; // Configuration
    
          sprintf(LangFile, "language/%s.txt", LanguageFile);
    
      std::ifstream inFile; 
      inFile.open(LangFile);
      if (!inFile)
       {
          cout << "Datei " << LangFile << " kann nicht geoeffnet werden!" << endl;
          exit(1);
       }
    
       do
       {
          // Komplette Zeile aus der Datei
          string line;
          // Zu extrahierende 'Felder' aus der Dateizeile
          string LangName, LangValue;
          // Konvertierungsstream
          std::istringstream is;
    
          // Zeile einlesen
          getline(inFile,line);
    
          // Bei erreichen des Dateiendes den Rest ueberspringen
          if (inFile.eof())
             continue;//letzte zeile Überspringen Blödsinn muss entfernt werden
          // Eingelesene Zeile dem Konvertierungsstream zuweisen
          is.str(line);
          // Nun Name und Value aus der Zeile extrahieren
          getline(is,LangName,'=');//   =
          getline(is,LangValue,';');//    ;
    
            if(LangName == "") continue;
            if(LangValue == "") continue;
    		if(LangName[0] == '#') continue;
    
          lang_str.insert(std::map<std::string,std::string>::value_type(LangName, LangValue));
    
       } while (!inFile.eof());
    
       // Datei wieder schliessen
       inFile.close();
    
        // Ausgabe des inhalts
        for(language_str::const_iterator i=lang_str.begin(); i!=lang_str.end(); ++i) {
            std::cerr<<i->first<<" => \""<<i->second<<"\""<<std::endl;}
    }
    

Anmelden zum Antworten