Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    30

    [c++] Aiuto con l'UNICODE

    Salve sto cercando di creare un programma che permetta di traslitterare i nomi russi con caratteri latini. Mi sono però imbattuto in problema, il codice è il seguente:

    switch(name[i])
    {
    case 'ш': name[i]='š'; break;
    case 'ч': name[i]='č'; break;
    default: break;
    }

    In corrispondenza delle prime due righe dello switch ho avuto il seguente warning:
    warning: multi-character character constant [-Wmultichar]

    Come faccio a risolvere? Se può servire sappiate che uso Code::Blocks 12.11 ed il mio sistema operativo è Ubuntu 12.04

    Già che ci sono volevo segnalare un altro problema: quando uso la funzione wcout visualizzo solo punti interrogativi; ad esempio digitando wcout << L"Il risultato è ", visualizzo: Il risultato ?. Non riesco a capire dove sbaglio, ho anche controllato le impostazione di Code::Blocks e del Terminale di Gnome, in entrambi i casi risulta in uso la codica UTF-8

  2. #2
    Ci sono essenzialmente due possibilità.
    Una è usare internamente wchar_t dovunque; 1 wchar_t = 1 codepoint Unicode (su Linux, dato che wchar_t => UCS-2; su Windows ci possono essere coppie surrogate dato che wchar_t => UTF-16), per cui lavori "normalmente" con un encoding a dimensione fissa.
    Ovviamente invece di usare funzioni/classi/costrutti che operano con char usi quelle per i wchar_t :std::wstring invece di std::string, std::wcout invece di std::cout, literal wide (prima dell'apice o del doppio apice c'è una L:
    codice:
    wchar_t uncarattere=L'è';
    const wchar_t * unastringa=L"una stringa";
    )
    Drawback: ogni wchar_t sono 4 byte (su Linux, 2 su Windows), per cui occupi tendenzialmente il quadruplo della memoria rispetto all'UTF-8 per testi prevalentemente con caratteri latini.

    In alternativa, lavori internamente in UTF-8, che è lo standard di fatto usato per la memorizzazione/output di file Unicode su Linux; problema: l'UTF-8 è un encoding a "larghezza variabile", per cui si va da 1 a 4 char necessari per memorizzare un codepoint Unicode, e "navigare" in una stringa UTF-8 non è semplicissimo, specie perché la libreria standard C++ non fornisce nulla di seriamente utile per gestirle (anche se c'è chi tenta di rimediare). Per portarsi dietro stringhe Unicode senza manipolarle UTF-8 è comodo, ma per fare il mestiere che vuoi tu è pessimo.

    Ergo: secondo me ti conviene lavorare con i wchar_t. In entrambi i casi, comunque, se inserisci caratteri "strani" nei sorgenti assicurati di salvarli in un encoding ben compreso dal compilatore (per g++ va più che bene UTF-8).

    In ogni caso, l'argomento è molto vasto e ognuno pare avere un'idea diversa sulla questione (si va da chi dice wchar_t internamente e convertire al momento dell'IO a chi dice di usare UTF-8 sempre a chi non raggiunge una conclusione ben definita).
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    30
    OK ho capito, avrei solo altre 2 domande:
    1. qual è l'opzione che devo mettere per far capire a g++ che sto lavorando con gli UNICODE?
    2. una volta che ho inserito tutti i wchar_t come mi hai suggerito tu, siamo sicuri che da terminale non visualizzerò più i punti interrogativi?

  4. #4
    Originariamente inviato da gila89
    OK ho capito, avrei solo altre 2 domande:
    1. qual è l'opzione che devo mettere per far capire a g++ che sto lavorando con gli UNICODE?
    Se il sorgente è in UTF-8 e usi i wchar_t come detto non dovresti fare null'altro di particolare.
    2. una volta che ho inserito tutti i wchar_t come mi hai suggerito tu, siamo sicuri che da terminale non visualizzerò più i punti interrogativi?
    Almeno su Linux, devi aggiungere un paio di altre cose all'inizio:
    codice:
            std::ios_base::sync_with_stdio(false);
            std::wcout.imbue(std::locale(""));
    questo fa sì che:
    - le classi di IO C++ non stiano sincronizzate con stdio "classico" C, evitando così che per le conversioni da wchar_t all'encoding usato dal terminale si faccia riferimento al locale C;
    - wcout usi per le conversioni il locale di default del sistema, e quindi dia in output al terminale i caratteri nell'encoding corretto (solitamente UTF8).

    Dovrai fare qualcosa di simile anche per l'input (come esattamente dipende da che genere di input hai - da console, da file, che encoding usa, ...).
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    30
    input da console

  6. #6
    Allora stessa cosa con wcin:
    codice:
            std::wcin.imbue(std::locale(""));
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2012
    Messaggi
    30
    OK allora provo ad inserire queste righe di codice e vediamo come va.

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 © 2024 vBulletin Solutions, Inc. All rights reserved.