Unicode - dove sbaglio

di il
29 risposte

Unicode - dove sbaglio

Ciao a tutti,
non mi è chiara una questione, sto scrivendo un programmino in C++.

Se scrivo:

	cout << "Oggi è una bella giornata" << endl;
La "e" accentata viene scritta sulla console windows correttamente (tabella caratteri OEM 850).

Ma se scrivo:

	char c = '\u00E8'; //o anche char c = '\0x00E8';
	cout << c << endl;
Mi viene stampato un quadratino. Perché?

Grazie mille,

29 Risposte

  • Re: Unicode - dove sbaglio

    La console dovrebbe supportare l'encoding iso-8859/codepage-1252, quindi non l'unicode.
    gli encoding dei caratteri 'strani' sono diversi

    http://string-functions.com/encodingtable.aspx?encoding=28591&decoding=1252
  • Re: Unicode - dove sbaglio

    migliorabile ha scritto:


    La console dovrebbe supportare l'encoding iso-8859/codepage-1252, quindi non l'unicode.
    gli encoding dei caratteri 'strani' sono diversi

    http://string-functions.com/encodingtable.aspx?encoding=28591&decoding=1252
    Grazie per il link e la tua interpretazione, sempre gentile Migliorabile, tuttavia, chiedo scusa, ci sono ancora alcune questioni che non mi sono chiare.

    La prima è che andando a vedere le impostazione della console di Windows 10 (cmd), vedo che è impostata la tabella caratteri 850 (OEM Multilingue latino I). In secondo luogo per la "e" con accento grave il valore tra le due tabelle, la mia e quella che mi hai passato corrispondo.

    Perché, come ho mostrato nel precedente posta, se alla cout passo una stringa con lo stesso carattere accentato funziona, mentre se gli passo un char con lo stesso carattere accentato non funzione? Nel caso di passaggio di stringa deve evidentemente fare una diversa "interpretazione"?

    Ma tenuto di ciò è come se char andasse in "overflow"!?!? - passami il termine - non è che devo usare altra struttura?

    Perché se dichiaro in Unicode
    char a = ''\u0041
    Ottengo la stampa correttà del carattere "A".

    Scusami tanto per le banalità, ma il mio codice dov'è sbagliato?
    Comunque non arrivo a riuscire a stampare correttamente valorizzando sia in decimale e/o in hex secondo le varie codifice.

    Grazie mille
  • Re: Unicode - dove sbaglio

    L'encoding dei caratteri e' un argomento decisamente subdolo e molto spesso NEMMENO chi ci lavora 8 ore al giorno 5 giorni la settimanat (gli HTML-isti) ci capisce qualcosa (vedasi i pasticci con i caratteri in siti istituzionali italiani).

    Ci sono diversi aspetti da considerare:

    1) i tool che usi di solito, in generale supportano l'UTF8, quindi Word, l'IDE che usi per lo viluppo software, ecc.
    2) Alcuni IDE SUPPORTANO l'iso 8859, QUINDI, quando fai copia/incolla da Word, ad esempio, sanno fare la conversione.
    3) Questo vuol dire che quando compili, compili in base all'encoding deciso dal'ambiente di sviluppo.
    4) quando stampi, usi l'encoding del device su cui vai a stampare. Per la console e' l'ISO 8859 (Windows-1252)

    Quindi, se i caratteri non cincidono, vuol dire che sono in gioco encoding diversi.

    La regola dovrebbe essere: si ragiona SEMPRE in UNICODE e suoi encoding (UTF-8, UTF16, UTF-32, ...).
    Se, quando si stampa qualcosa, non escono i caratteri giusti, si deve trovare il modo di far accettare al dispositivo l'UNICODE: o lo accetta mediante qualche configurazione, OPPURE si implementa uno strato di adattamento che converte DA UNICODE all'encoding specifico del dispositivo, ad esempio da UNCODE a ISO8859.

    Ed, ovviamente, vale anche il contrario

    Nota: CP 850, Iso 8859-1, Windows 1252 in pratica sono sempre la stessa cosa.
    Non ho seguito l'evoluzione storica e ci sono alcune variazioni, ma su wikipedia puoi trovare un po' di documentazione

    https://en.wikipedia.org/wiki/Code_page_85
    https://en.wikipedia.org/wiki/ISO/IEC_8859-
    https://en.wikipedia.org/wiki/Windows-125
    https://en.wikipedia.org/wiki/ISO_8859-1
  • Re: Unicode - dove sbaglio

    migliorabile ha scritto:


    L'encoding dei caratteri e' un argomento decisamente subdolo e molto spesso NEMMENO chi ci lavora 8 ore al giorno 5 giorni la settimanat (gli HTML-isti) ci capisce qualcosa (vedasi i pasticci con i caratteri in siti istituzionali italiani).

    Ci sono diversi aspetti da considerare:

    1) i tool che usi di solito, in generale supportano l'UTF8, quindi Word, l'IDE che usi per lo viluppo software, ecc.
    2) Alcuni IDE SUPPORTANO l'iso 8859, QUINDI, quando fai copia/incolla da Word, ad esempio, sanno fare la conversione.
    3) Questo vuol dire che quando compili, compili in base all'encoding deciso dal'ambiente di sviluppo.
    4) quando stampi, usi l'encoding del device su cui vai a stampare. Per la console e' l'ISO 8859 (Windows-1252)

    Quindi, se i caratteri non cincidono, vuol dire che sono in gioco encoding diversi.

    La regola dovrebbe essere: si ragiona SEMPRE in UNICODE e suoi encoding (UTF-8, UTF16, UTF-32, ...).
    Se, quando si stampa qualcosa, non escono i caratteri giusti, si deve trovare il modo di far accettare al dispositivo l'UNICODE: o lo accetta mediante qualche configurazione, OPPURE si implementa uno strato di adattamento che converte DA UNICODE all'encoding specifico del dispositivo, ad esempio da UNCODE a ISO8859.

    Ed, ovviamente, vale anche il contrario

    Nota: CP 850, Iso 8859-1, Windows 1252 in pratica sono sempre la stessa cosa.
    Non ho seguito l'evoluzione storica e ci sono alcune variazioni, ma su wikipedia puoi trovare un po' di documentazione

    https://en.wikipedia.org/wiki/Code_page_85
    https://en.wikipedia.org/wiki/ISO/IEC_8859-
    https://en.wikipedia.org/wiki/Windows-125
    https://en.wikipedia.org/wiki/ISO_8859-1
    Caro Migliorabile,
    grazie delle tue ulteriori considerazioni e fonti.
    Allora quando inizio ad apprendere un nuovo linguaggio a riprendere un linguaggio che è molto tempo che non uso, uso sempre un editor di testo (niente IDE) e compilatore a console. Quindi ho impostato il charset di Notepad++ a OEM 850. Ma non funziona! Non capisco poi, comunque io sto imponendo il valore della variabile char in esadecimale, non la sto assegnado con il carattere accentato.

    Continuo a non capire però perché a prescindere dal charset di Notepad++ se passo una stringa le e accentate le stampa corrette a console.

    Approfondirò i links. Sono convinto che se scrivo lo stesso codice in C funzione!

    Io uso g++ per compilare.

    Ancora grazie mille per la tua sempre pronta disponibilità e competenza.
  • Re: Unicode - dove sbaglio

    Nota: NON SERVE quotare l'intero testo. Lo si fa SOLO per le parti interessanti o di qualche importanza.
  • Re: Unicode - dove sbaglio

    Hai ragione, chiedo scusa!
  • Re: Unicode - dove sbaglio

    migliorabile ha scritto:


    (vedasi i pasticci con i caratteri in siti istituzionali italiani).
    Questo, in gergo tecnico, si chiama "sparare sulla Croce Rossa".

    @deckard: credo che il problema non sia solo nelle varie code page ma, in questo caso, nel fatto che ci sono funzioni che accettano/vogliono stringhe con una certa codifica (in windows: ascii, ansi, utf-8, unicode) e funzioni che ne accettano una diversa ma, comunque, non altre.
    Se guardi le API di Windows vedrai che la maggior parte delle funzioni "esiste" in due varianti: OpenPrinterA e OpenPrinterW.

    Se dai in pasto ad una funzione una stringa con una codifica che non si aspetta, tu puoi aspettarti un bel casino. Semplice!
  • Re: Unicode - dove sbaglio

    Grazie nicolap,
    dopo mi studio quanto mi hai scritto.

    Grazie mille anche a te!
  • Re: Unicode - dove sbaglio

    migliorabile ha scritto:


    L'encoding dei caratteri e' un argomento decisamente subdolo
    Adesso, non esageriamo, in realtà è banale
    e molto spesso NEMMENO chi ci lavora 8 ore al giorno 5 giorni la settimanat (gli HTML-isti) ci capisce qualcosa (vedasi i pasticci con i caratteri in siti istituzionali italiani).
    Questo purtroppo è vero

    La regola dovrebbe essere: si ragiona SEMPRE in UNICODE e suoi encoding (UTF-8, UTF16, UTF-32, ...).
    Non sono molto d'accordo.

    La ratio, come al solito (non mi riferisco specificamente a qualcuno, in generale), è "se vai a casaccio senza sapere bene cosa fai, e perchè, non sorprenderti se i risultati sono diversi da quanto atteso"
    Corollario
    casaccio=veloce=disastro

    Qui dovrebbe scattare il pippone-spiegone cosmico, purtroppo il cambio dell'ora ha forzato la ricompilazione di ogni singola riga dei miei programmi e quindi sono impegnatissimo.
    Magari verso metà prox settimana "tutto quello che avreste voluto sapere, e che in realtà avreste dovuto"
  • Re: Unicode - dove sbaglio

    +m2+ ha scritto:


    La ratio, come al solito (non mi riferisco specificamente a qualcuno, in generale), è "se vai a casaccio senza sapere bene cosa fai, e perchè, non sorprenderti se i risultati sono diversi da quanto atteso"
    Corollario
    casaccio=veloce=disastro
    Ciao +m2+,
    confesso che probabilmente sono andato a casaccio, in realtà mi sono soffermato, incidentalmente a questo problema per puro caso, mi sto leggendo un libro per riprendere il C++ e umilmente sto iniziando come da zero. Per puro caso mi è venuta la "malsana" idea di mettere un "è" in un char. Ho detto lavoro rimappando la tavola del charset OEM 850. Ho posto come "stranezza" come mai cout stampa correttamente una string in cui c'è "è" ma non un char con la stessa "è"...

    So di non sapere.

    Grazie anche per il tuo intervento, che con pazienza non tarda mai arrivare.

    Per quanto riguarda a quanto consigliav nicolap vorrei una soluzione cross-platform e non legata a librerie di windows.

    Grazie ancora a tutti
  • Re: Unicode - dove sbaglio

    Parti già malissimo faceno un assunto che è falso.
    un testo è esattamente come qualsiasi altro file o flusso.
    Se non sai come è codificato non lo potrai fare.

    Se ti do un file e non sai se è un jpg, bmp o gif o magari un mp3 non ti sorprendi se non lo visualizzi.

    Stessa identica cosa per i caratteri che sono ormai unicode. Il punto è che di codifiche ce ne sono tantissime, così come ci sono tanti formati grafici.

    Quindi il testo non esiste, esiste contenuto e codifica.

    Ecco perché char inteso come 8 bit non esiste più da una ventina di anni (ovviamente per un programmatore di media competenza).
  • Re: Unicode - dove sbaglio

    Ciao +m2+,
    quale sarebbe l'assunto a cui ti riferisci? Questa volta faccio fatica a seguire il tuo ragionamento.
    Che i caratteri siano in Unicode, credo di saperlo, so anche che esistono alcune varianti. Con questo non voglio affermare che sono un maestro sul tema. Mi pare che tutti i miei post si siano proprio concentrati sulla codifica, non sul contenuto.

    Infine, quando dici, "Se ti do un file e non sai se è un jpg, bmp o gif o magari un mp3 non ti sorprendi se non lo visualizzi." dici il una cosa da un punto di vista logico non del tutto corretta, in sé hai messo un piccola contraddizione. Se mi dai un file jpg, bmp, o gif stai presumendo e non è difficile desumerne il suo formato.

    Un saluto e grazie comunque.
  • Re: Unicode - dove sbaglio

    Piuttosto che impiegare i Code Page, come riportato nella documentazione MS. per risultati più coerenti, le applicazioni devono utilizzare Unicode, come UTF-8 o UTF-16, anziché una tabella codici specifica:
    https://docs.microsoft.com/en-us/windows/desktop/intl/code-page-identifiers
    Nell'ambito della codifica dei caratteri, in modo da farsi una idea su quella che è stata la evoluzione che ha portato al sistema Unicode, si può leggere questo documento:

    mentre per quanto riguarda la applicabilità, della codifica Unicode, nel linguaggio di programmazione si possono leggere i seguenti link:
    https://unicodebook.readthedocs.io/programming_languages.html
    https://gustedt.wordpress.com/2017/03/09/unicode-operators-for-c/
    https://www.cprogramming.com/tutorial/unicode.htm
  • Re: Unicode - dove sbaglio

    deckard ha scritto:


    Che i caratteri siano in Unicode, credo di saperlo, so anche che esistono alcune varianti. Con questo non voglio affermare che sono un maestro sul tema. Mi pare che tutti i miei post si siano proprio concentrati sulla codifica, non sul contenuto.
    Di quali caratteri parli? In generale la tua assunzione è sbagliata.
    Infine, quando dici, "Se ti do un file e non sai se è un jpg, bmp o gif o magari un mp3 non ti sorprendi se non lo visualizzi." dici il una cosa da un punto di vista logico non del tutto corretta, in sé hai messo un piccola contraddizione. Se mi dai un file jpg, bmp, o gif stai presumendo e non è difficile desumerne il suo formato.
    Sintetico si ma contraddittorio direi proprio di no!
    Dato un file generico, desumerne il tipo può essere estremamente difficile, tranne che per i formati più comuni.
Devi accedere o registrarti per scrivere nel forum
29 risposte