Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. 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)
Guru


Messaggi: 700
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


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1620
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)
Guru


Messaggi: 700
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!


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
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 ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
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.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
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 ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
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 ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
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!!! :-|


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6403
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 ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo