Oppure

Loading
19/07/16 22:22
AldoBaldo
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)

#include <stdio.h>
#include <stdlib.h>

#define XCONSOLE(c) c<128 ? c : XConsole[c-128]

static const unsigned char XConsole[] = { // 16 per riga
    128,129,39,102,34,133,43,135,136,137,83,60,140,141,90,143,         // da 128
    144,39,39,34,34,149,45,45,126,153,115,62,156,157,122,152,          // da 144
    255,173,189,156,207,190,221,245,249,184,166,34,170,45,169,238,     // da 160
    248,241,253,252,239,230,20,250,247,251,167,34,172,171,243,168,     // da 176
    183,181,182,199,142,143,146,128,212,144,210,211,222,214,215,216,   // da 192
    209,165,227,224,226,229,153,158,157,235,233,234,154,237,232,225,   // da 208
    133,160,131,198,132,134,145,135,138,130,136,137,141,161,140,139,   // da 224
    208,164,149,162,147,228,148,246,155,151,163,150,129,236,232,152 }; // da 240

int main() {
    const char *p;
    FILE *f;
    int c;

    if( (f=fopen("file.txt","r")) != NULL ) {
        printf( "\nDa file:\n\n" );

        for( c=fgetc(f); c!=EOF; c=fgetc(f) )
            printf( "%c", XCONSOLE(c) );

        fclose( f );
    }

    ////////////////////////

    printf( "\n\nDa stringa:\n\n" );

    for( p="Funziona o non funziona? Perché sì e perché no?\n"; *p; ++p )
        printf( "%c", XCONSOLE((unsigned char)*p) );

    for( p="Forse per «l’umidità»? Ce n’è più che in pedalò!\n"; *p; ++p )
        printf( "%c", XCONSOLE((unsigned char)*p) );

    return 0;
}


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 19/07/16 22: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.
19/07/16 22:54
TheDarkJuster
In realtà il modo standard è di usare la libreria icu, o il tipo wchar che varia con compilatore e/o sistema operativo...
aaa
19/07/16 23:55
AldoBaldo
Grazie per la segnalazione, ma ho cercato la libreria icu (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.
20/07/16 7:54
Devi usare il locale corretto e i wchar

#include <wchar.h>
#include <locale.h>

int main(){

    setlocale(LC_ALL, ".437");
    wchar_t stringa[] = L"Funziona o non funziona? Perché sì e perché no?\nForse per «l’umidità»? Ce n’è più che in pedalò!\n";
    wprintf(L"%s", stringa);
    
    return 0;
}
20/07/16 13:22
AldoBaldo
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:

#include <wchar.h>
#include <locale.h>

int main(){

    setlocale(LC_ALL, ".437");
    wchar_t stringa[8];
    for( int i=0; i<8; ++i )
        stringa[i] = (unsigned char)("Perché?\n"[i]);
    wprintf(L"%s", stringa);

    return 0;
}


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.
20/07/16 16:00
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 20/07/16 16:03
20/07/16 16:03
Funziona


In quel caso sei tu che stai copiando il singolo byte ASCII nello short int usato per il wchar (2 byte).
20/07/16 17:10
AldoBaldo
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.