Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Caratteri oltre 0-127 in console
Forum - C/C++ - Caratteri oltre 0-127 in console

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 0:22
Mercoledì, 20/07/2016
Ciao a te che leggi!

Per passatempo, sto mettendo insieme un programmino che gradirei potesse leggere dei file di testo trasferendone i contenuti in console senza fare troppo lo schizzinoso in termini di caratteri accentati, punteggiature bislacche, ecc. Ho cercato un po' qua e là in rete per scoprire se esistono metodi "standard" per poter usare in console i caratteri ASCII estesi (oltre 0-127, fino a 255), ma non ho avuto un gran successo. E va be'... trattandosi di un passatempo posso permettermi di fare esperimenti, quindi...

...quindi ho pensato di mettere insieme una tabella di conversione esplorando empiricamente le corrispondenze tra un set di caratteri completo 0-255 e il modo in cui quei caratteri vengono scritti in console. E vengo quindi alla domanda:

Il metodo qui sotto, può avere validità generale o per qualche ragione è efficace solo nell'ambiente particolare nel quale l'ho sviluppato e provato? (Code::blocks con MinGW, credo versione 3.20, su Windows 7)

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define XCONSOLE(c) c<128 ? c : XConsole[c-128]
  5.  
  6. static const unsigned char XConsole[] = { // 16 per riga
  7.     128,129,39,102,34,133,43,135,136,137,83,60,140,141,90,143,         // da 128
  8.     144,39,39,34,34,149,45,45,126,153,115,62,156,157,122,152,          // da 144
  9.     255,173,189,156,207,190,221,245,249,184,166,34,170,45,169,238,     // da 160
  10.     248,241,253,252,239,230,20,250,247,251,167,34,172,171,243,168,     // da 176
  11.     183,181,182,199,142,143,146,128,212,144,210,211,222,214,215,216,   // da 192
  12.     209,165,227,224,226,229,153,158,157,235,233,234,154,237,232,225,   // da 208
  13.     133,160,131,198,132,134,145,135,138,130,136,137,141,161,140,139,   // da 224
  14.     208,164,149,162,147,228,148,246,155,151,163,150,129,236,232,152 }; // da 240
  15.  
  16. int main() {
  17.     const char *p;
  18.     FILE *f;
  19.     int c;
  20.  
  21.     if( (f=fopen("file.txt","r")) != NULL ) {
  22.         printf( "\nDa file:\n\n" );
  23.  
  24.         for( c=fgetc(f); c!=EOF; c=fgetc(f) )
  25.             printf( "%c", XCONSOLE(c) );
  26.  
  27.         fclose( f );
  28.     }
  29.  
  30.     ////////////////////////
  31.  
  32.     printf( "\n\nDa stringa:\n\n" );
  33.  
  34.     for( p="Funziona o non funziona? Perché sì e perché no?\n"; *p; ++p )
  35.         printf( "%c", XCONSOLE((unsigned char)*p) );
  36.  
  37.     for( p="Forse per «l’umidità»? Ce n’è più che in pedalò!\n"; *p; ++p )
  38.         printf( "%c", XCONSOLE((unsigned char)*p) );
  39.  
  40.     return 0;
  41. }



Il file "file.txt" contiene lo stesso testo delle stringhe, ovvero:

Funziona o non funziona? Perché sì e perché no?
Forse per «l’umidità»? Ce n’è più che in pedalò!


Son certo che apprezzerai l'estro poetico del testo di prova... :rotfl:

Ultima modifica effettuata da AldoBaldo il 20/07/2016 alle 0:29


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1453
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 0:54
Mercoledì, 20/07/2016
In realtà il modo standard è di usare la libreria icu, o il tipo wchar che varia con compilatore e/o sistema operativo...

PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 1:55
Mercoledì, 20/07/2016
Grazie per la segnalazione, ma ho cercato la libreria icu (http://site.icu-project.org/) e la trovo un po' "ipertrofica" per quelli che sono i miei scopi e le mie capacità.

Ho provato anche a usare stringhe di wchar_t, ma senza molto successo.

Non conosci qualche metodo più semplice e "snello" verso il quale indirizzarmi? (ammesso che esista)
Mi sembra impossibile che una caratteristica tanto di base non sia facilmente disponibile!


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 9:54
Mercoledì, 20/07/2016
Devi usare il locale corretto e i wchar

Codice sorgente - presumibilmente C++

  1. #include <wchar.h>
  2. #include <locale.h>
  3.  
  4. int main(){
  5.  
  6.     setlocale(LC_ALL, ".437");
  7.     wchar_t stringa[] = L"Funziona o non funziona? Perché sì e perché no?\nForse per «l’umidità»? Ce n’è più che in pedalò!\n";
  8.     wprintf(L"%s", stringa);
  9.    
  10.     return 0;
  11. }



Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 15:22
Mercoledì, 20/07/2016
Grazie nessuno, mi dai dei begli spunti.

Ho provato a compilare il codice del tuo suggerimento, ma c'è un errore che mi blocca:

error: converting to execution character set: Illegal byte sequence

Testardo, ho provato a fare una modifica:

Codice sorgente - presumibilmente C++

  1. #include <wchar.h>
  2. #include <locale.h>
  3.  
  4. int main(){
  5.  
  6.     setlocale(LC_ALL, ".437");
  7.     wchar_t stringa[8];
  8.     for( int i=0; i<8; ++i )
  9.         stringa[i] = (unsigned char)("Perché?\n"[i]);
  10.     wprintf(L"%s", stringa);
  11.  
  12.     return 0;
  13. }



Funziona, ma non riesco a capire come e perché. Cioè, com'è che funziona se inizializzo la stringa carattere per carattere con l'equivalente unsigned dei singoli caratteri e non funziona se la inizializzo direttamente dalla stringa costante L"qualcosa"? E' un bel mistero...

In attesa d'una risposta, se vorrai darmela, faccio qualche altra ricerchina ragionando su quel che mi hai fatto scoprire. Ma non è che sia molto fiducioso -- probabilmente non troverò niente che io sia in grado di comprendere da solo.


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 18:00
Mercoledì, 20/07/2016
Per gcc/mingw aggiungi lo switch di compilazione (nelle opzioni)

-finput-charset=iso-8859-1

e nella frase utilizza l'apice corretto

wchar_t stringa[] = L"Funziona o non funziona? Perché sì e perché no?\nForse per «l'umidità»? Ce n'è più che in pedalò!\n";


P.S. Io ho usato Visual C++ ...

Ultima modifica effettuata da nessuno il 20/07/2016 alle 18:03


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 18:03
Mercoledì, 20/07/2016
Testo quotato

Funziona



In quel caso sei tu che stai copiando il singolo byte ASCII nello short int usato per il wchar (2 byte).


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 19:10
Mercoledì, 20/07/2016
Ho aggiunto quella formula allo switch di compilazione e l'errore non viene più segnalato. Eppure, nell'uscita in console si "mangia" alcuni caratteri (nell'esempio specifico, gli apostrofi tondi). Ma che storia!!! :-|


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 19:31
Mercoledì, 20/07/2016
Non hai letto la mia nota sull'apostrofo... eppure avevo riportato la frase corretta


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo