Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it L'avatar di Orione
    Registrato dal
    Oct 2002
    Messaggi
    148

    [c++] Caratteri russi ed altro

    Ciao a tutti, vi dico subito che di c++ ne so ben poco, ho creato un file xml per la gestione delle varie lingue ma certi caratteri come il russo, alcuni caratteri per lo spagnolo ecc..non riesco a codificarli.

    Per esempio la stringa

    <Russo>Выход</Russo>

    if(tmp.find("<Russo>") != NULL_U)
    {
    unsigned pos_s = tmp.find("<Russo>")+7;
    unsigned pos_f = tmp.find("</Russo>");
    lg.setRusso(tmp.substr (pos_s,pos_f-pos_s));
    }

    tmp è la riga che leggo sul xml

    quando faccio tmp.substr.... mi escono caratteri completamente diversi(Выход), qualcuno può aiutarmi a leggere correttamente? Caratteri di questo tipo mi escono comunque non solo per il russo ma per tutti quei caratteri particolari come é , ecc

  2. #2
    Su che piattaforma lavori? Che encoding stai usando per il file da cui leggi?
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di Orione
    Registrato dal
    Oct 2002
    Messaggi
    148
    il file xml delle traduzioniè cosi fatto

    <?xml version="1.0" encoding="utf-8" ?>
    <Traduzioni>
    <Languages>
    <Language>
    <KeyName>Logout</KeyName>
    <Italiano>Disconnetti</Italiano>
    <Inglese>Logout</Inglese>
    <Spagnolo>Salir</Spagnolo>
    <Tedesco>Abmelden</Tedesco>
    <Francese>Déconnexion</Francese>
    <Russo>Выход</Russo>
    </Language>
    </Languages>
    </Traduzioni>

    e uso visual studio 2010 pro

  4. #4
    Utente di HTML.it L'avatar di Orione
    Registrato dal
    Oct 2002
    Messaggi
    148
    Ci sono quasi, ovvero sono riuscito a leggere la string, adesso ho una variabile std::wstring tmp che assume il valore della stringa del file xml.

    Quindi tmp è adesso uguale a <Russo>Выход</Russo>

    Nel mio primo codice usavo una string e di conseguenza mi funzionava il find e la substring come scritto nel primo post, ora sto cercando di farli funzionare per la wstring come si fa?
    ovvero come scrivo il codice qua sotto con la variabile tmp come wstring?

    if(tmp.find("<Russo>") != NULL_U)
    {
    unsigned pos_s = tmp.find("<Russo>")+7;
    unsigned pos_f = tmp.find("</Russo>");
    lg.setRusso(tmp.substr (pos_s,pos_f-pos_s));
    }



    Grazie a tutti

  5. #5
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    I literal per wstring vanno preceduti da L
    codice:
    if(tmp.find(L"<Russo>") != NULL_U)
    {
        unsigned pos_s = tmp.find(L"<Russo>")+7;
        unsigned pos_f = tmp.find(L"</Russo>");
        lg.setRusso(tmp.substr (pos_s,pos_f-pos_s));
    }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  6. #6
    Utente di HTML.it L'avatar di Orione
    Registrato dal
    Oct 2002
    Messaggi
    148
    Ok perfetto adesso funziona la lettura dei vari caratteri, e nella variabile wstring ho i dati voluti. Purtroppo non è ancora finita, dovrei passare questi dati mediante una funzione ad un dispositivo che accetta solo char *.
    Ho provato a convertire la variabile in questo modo

    string str(ws.begin(),ws.end());

    dove ws è la variabile wstring con i dati caricati dal file xml

    funzione((char *)str.c_str());

    ma invece di mantenermi i caratteri originali me li cambia

    Idee su come convertirli in modo da mantenere i caratteri russi o altri caratteri strani che durante la conversione perde?

  7. #7
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Non puoi cambiare caratteri da unicode ad ansi con un cast, ma serve una conversione.
    Dato che di C++ ne sai poco ti do il codice per la conversione.
    Tra gli include va messo:
    #include <windows.h>

    Sistema tu l'identazione se serve.
    Da wstring a string:
    codice:
    // cp: Codepage di Windows.
    // ws: wstring da convertire
    // s: string convertita 
    inline void Encode(UINT cp, const std::wstring& ws, std::string& s) {
        int sz = ::WideCharToMultiByte(cp,0,ws.c_str(),ws.size(),0,0,0,0);
        s.resize(sz);
        WideCharToMultiByte(cp,0,ws.c_str(),ws.size(),&s[0],s.size(),0,0);
    }
    da string a wstring:
    codice:
    // cp: Codepage di Windows.
    // s: string da convertire
    // ws: wstring convertita 
    inline void Decode(UINT cp,const std::string& s, std::string& ws) {
       int len = MultiByteToWideChar(
                         cp,
                         MB_PRECOMPOSED |  MB_ERR_INVALID_CHARS,
                         s.c_str(),
                         s.size(),0,0
                    );
        ws.resize(len);
        MultiByteToWideChar(
            cp,
            MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
            s.c_str(),s.size(),&ws[0],ws.size()
         );
    }
    I codici da usare per cp sono qui:
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    I più usati sono:
    CP_ACP
    CP_UTF8
    CP_OEM

    Esempio:
    codice:
    wstring a = L"€€€€";
    string b;
    Encode(CP_UTF8,a,b);
    Fa un po' di esperimenti con i codepage (anche se immagino dovrai usare CP_UTF8).
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Correzione:
    In Decode sostituisci
    MB_PRECOMPOSED | MB_ERR_INVALID_CHARS
    con 0 (zero).
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  9. #9
    Utente di HTML.it L'avatar di Orione
    Registrato dal
    Oct 2002
    Messaggi
    148
    CIAO

    ho provato a fare le prove come mi hai indicato ma non mi funziona e non so dove sto sbagliando. Ho fatto girare la tua stessa funzione in questo modo:

    string s;
    wstring b = L"Выход";
    Encode(CP_UTF8,b,s);

    ma la variabile s viene restituita come Выход

    ho dovuto mettere 0 (zero) al posto della MB_PRECOMPOSED | MB_ERR_INVALID_CHARS
    anche nell'encode altrimenti mi restituiva una stringa nulla.
    Ho cambiato anche i vari cp provandone veri ma come sempre mi restituisce sempre caratteri diversi da quelli passati.

  10. #10
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Come ti ho detto è una codifica.
    Nel set ANSI non esistono caratteri russi come invece in UNICODE, per cui è necessario trasformare uno o più caratteri russi in una sequenza che in apparenza non significa nulla, ma che mantiene le corrette informazioni in caso di decodifica.
    Per cui è normale vedere caratteri "strani" quando non si ha a che fare con le codifiche UNICODE dei caratteri latini "a,b,c" etc (per la cronaca è stato codificato anche il Klingon!).
    Puoi pensarlo come a un processo di "zip" al contrario (dato che non si comprime ma si si espande).
    La codifica UTF8 è la più efficente per i caratteri europei, ma dispensiosa per i caratteri cirillici, cinesi, giapponesi etc (per i dettagli ti rimando qui: http://it.wikipedia.org/wiki/UTF-8 )
    Per cui se non vuoi (dal tuo punto di vista) "perdere caratteri" o farli rimanere a te comprensibili devi lavorare in UNICODE tramite wstring.

    Questo per la teoria.

    Hai parlato di una funzione che accetta solo char* : l'hai scritta tu? A cosa ti riferisci con dispositivo?
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.