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
Code Pages - codepages.cpp

codepages.cpp

Caricato da: AldoBaldo
Scarica il programma completo

  1. /** =========== CODE PAGES v1.0 - luglio 2016, di Aldo Carpanelli ==============
  2. Il programma permette di "ispezionare" il code page (character set) usato nella
  3. console del C nell'ambito di una certa localizzazione.
  4. Funziona solo in ambiente Windows, non portabile.
  5. =============================================================================**/
  6.  
  7. /** ===> INCLUSIONI <======================================================= **/
  8.  
  9. #include "codepages.h"
  10.  
  11. /** ===> GLOBALI <========================================================== **/
  12.  
  13. int gColCons; // il numero delle colonne in console
  14.  
  15. /** ===> DEFINIZIONI DI FUNZIONI <========================================== **/
  16.  
  17. int main() {
  18.     const int kDimBuff   = 1088;
  19.     const int kDimMaxLoc =  256;
  20.     char *buff = (char*)malloc(kDimBuff); // per le tabelle
  21.     char *loc  = (char*)malloc(kDimMaxLoc); // per le stringhe di localizzazione
  22.     int azione; // il comando scelto tramite il menu
  23.  
  24.     if( buff != NULL && loc != NULL ) { // buffers allocati
  25.         sprintf( loc, "%s", setlocale(LC_ALL,NULL) ); // localizzazione corrente
  26.  
  27.         if( RicavaNumeroColonneConsole() ) {
  28.             ImpostaTitoloFinestra( kStrNomeProgramma ); // irrilevante
  29.             ImpostaColoriConsole( COL_DFLT ); // irrilevante
  30.  
  31.             do { // scelta dei comandi
  32.                 switch( azione = Menu() ) {
  33.                     case kCmndCambiaLocale:
  34.                         CambiaLocale( loc, kDimMaxLoc, buff, kDimBuff );
  35.                         break;
  36.                     case kCmndCar_0_31:
  37.                         VisualizzaTabella( loc, buff, 0 );
  38.                         break;
  39.                     case kCmndCar_32_127:
  40.                         VisualizzaTabella( loc, buff, 1 );
  41.                         break;
  42.                     case kCmndCar_128_255:
  43.                         VisualizzaTabella( loc, buff, 2 );
  44.                         break;
  45.                     default: ;
  46.                 }
  47.  
  48.             } while( azione != kCmndEsci );
  49.         }
  50.         else {
  51.             Errore( kStrErrDimConsoleIlleggibili );
  52.         }
  53.     }
  54.     else {
  55.         Errore( kStrErrMemoriaInsuff );
  56.     }
  57.  
  58.     // deallocazione della memoria dinamica
  59.     if( buff != NULL ) free( buff );
  60.     if( loc != NULL ) free( loc );
  61.  
  62.     return 0;
  63. }
  64.  
  65. /*==============================================================================
  66. Si assicura che la console sia larga a sufficienza per poter contenere le
  67. tabelle (almeno 74 colonne).
  68. ==============================================================================*/
  69.  
  70. bool RicavaNumeroColonneConsole( void ) {
  71.     HANDLE hConsole = GetStdHandle( STD_OUTPUT_HANDLE );
  72.     bool esito = false;
  73.  
  74.     gColCons = 80; // di solito e' cosi', ma...
  75.  
  76.     if( hConsole != NULL && hConsole != INVALID_HANDLE_VALUE ) {
  77.         CONSOLE_SCREEN_BUFFER_INFO csbi = {0};
  78.  
  79.         if( GetConsoleScreenBufferInfo(hConsole,&csbi) ) {
  80.             if( csbi.dwSize.X < 74 ) csbi.dwSize.X = 74;
  81.             if( SetConsoleScreenBufferSize(hConsole,csbi.dwSize) )
  82.                 { gColCons = csbi.dwSize.X; esito = true; }
  83.         }
  84.     }
  85.  
  86.     return esito;
  87. }
  88.  
  89. /*==============================================================================
  90. Irrilevante. Cambia il titolo della finestra della console.
  91. ==============================================================================*/
  92.  
  93. void ImpostaTitoloFinestra( const char *titolo ) {
  94.     SetConsoleTitle( titolo );
  95. }
  96.  
  97. /*==============================================================================
  98. Irrilevante. Cambia i colori del testo e dello sfondo della console.
  99. ==============================================================================*/
  100.  
  101. void ImpostaColoriConsole( WORD colori ) {
  102.     HANDLE hConsole = GetStdHandle( STD_OUTPUT_HANDLE );
  103.     SetConsoleTextAttribute( hConsole, colori );
  104. }
  105.  
  106. /*==============================================================================
  107. Gestisce il menu per la scelta delle operazioni da compiere.
  108. ==============================================================================*/
  109.  
  110. int Menu( void ) {
  111.     int i, aux, scelta = -2;
  112.     char buffer[16] = {'\0'};
  113.     char *fine;
  114.  
  115.     do {
  116.         CLS;
  117.  
  118.         if( scelta < 0 ) {
  119.             Box( kStrBoxTitolo_1, gColCons-2, -1, true, true );
  120.             A_CAPO; A_CAPO;
  121.  
  122.             for( i=1; i<kTotVociMenu; ++i )
  123.                 printf( " %3d. %s\n", i, kStrVociMenu[i] );
  124.             printf( " %3d. %s\n", 0, kStrVociMenu[0] );
  125.  
  126.             if( scelta < -1 ) {
  127.                 ImpostaColoriConsole( GIALLO );
  128.                 printf( "\n%s", kStrSceltaComando_1 );
  129.                 ImpostaColoriConsole( COL_DFLT );
  130.             }
  131.             else {
  132.                 ImpostaColoriConsole( ROSSO );
  133.                 printf( "\n%s", kStrSceltaComando_2 );
  134.                 ImpostaColoriConsole( COL_DFLT );
  135.             }
  136.  
  137.         }
  138.  
  139.         fgets( buffer, 16, stdin );
  140.         aux = strtoul( buffer, &fine, 10 );
  141.         if( buffer[strlen(buffer)-1]!='\n' )
  142.             while( getchar()!='\n' );
  143.  
  144.         if( fine != buffer )
  145.             scelta = aux;
  146.         else scelta = -1;
  147.  
  148.         if( scelta < 0 || scelta >= kTotVociMenu )
  149.             scelta = -1;
  150.     } while( scelta < 0 );
  151.  
  152.     return scelta;
  153. }
  154.  
  155. /*==============================================================================
  156. Gestisce l'input per il cambiamento della localizzazione corrente.
  157. ==============================================================================*/
  158.  
  159. void CambiaLocale( char *loc, int dimMaxLoc, char *buff, int dimBuff ) {
  160.     char *pLoc = NULL;
  161.  
  162.     do {
  163.         CLS;
  164.         sprintf( loc, "%s", setlocale(LC_ALL,NULL) );
  165.         Box( kStrBoxTitolo_2, gColCons-2, -1, true, false );
  166.         A_CAPO; A_CAPO;
  167.         printf( kStrEtichLocale );
  168.         printf( "\"%s\"", loc );
  169.         A_CAPO; A_CAPO;
  170.         ImpostaColoriConsole( GIALLO );
  171.         printf( kStrRichiestaLocale );
  172.         ImpostaColoriConsole( COL_DFLT );
  173.         A_CAPO; A_CAPO; SPAZI(1);
  174.  
  175.         fgets( buff, dimBuff, stdin );
  176.         int l = strlen( buff );
  177.         if( buff[l-1] == '\n' )
  178.             buff[--l] = '\0';
  179.         else while(getchar()!='\n');
  180.  
  181.         if( l == 0 )
  182.             pLoc = setlocale( LC_ALL, "" ); // default di sistema
  183.         else pLoc = setlocale( LC_ALL, buff );
  184.  
  185.         if( pLoc == NULL ) {
  186.             Errore( kStrErrStrLocIgnota );
  187.             continue;
  188.         }
  189.         else {
  190.             sprintf( loc, "%s", pLoc );
  191.             A_CAPO;
  192.             printf( kStrEtichLocale );
  193.             printf( "\"%s\"", loc );
  194.             A_CAPO; A_CAPO; SPAZI(1);
  195.             PAUSE;
  196.             break;
  197.         }
  198.     } while( true );
  199. }
  200.  
  201. /*==============================================================================
  202. "Smista" i comandi di visualizzazione delle tabelle, scegliendo la funzione piu'
  203. opportuna in relazione al parametro "tipo".
  204. ==============================================================================*/
  205.  
  206. void VisualizzaTabella( const char *loc, char *buff, int tipo ) {
  207.     const char *titolo[] = { kStrTitTab_1, kStrTitTab_2, kStrTitTab_3 };
  208.     int intAux;
  209.  
  210.     CLS;
  211.  
  212.     intAux = sprintf( buff, kStrSottoTitTab );
  213.     sprintf( buff+intAux, "\"%s\"", loc ); A_CAPO;
  214.     ImpostaColoriConsole( GIALLO );
  215.     Centrato( buff, gColCons ); A_CAPO;
  216.     Centrato( titolo[tipo], gColCons ); A_CAPO;
  217.     ImpostaColoriConsole( COL_DFLT );
  218.  
  219.     if( tipo == 0 )
  220.         Box( ListaCaratteri_0_31(buff), 40, -1, true, true );
  221.     else if( tipo == 1 )
  222.         Box( ListaCaratteri_32_127(buff), 56, -1, true, true );
  223.     else Box( ListaCaratteri_128_255(buff), 72, -1, true, true );
  224.  
  225.     A_CAPO; A_CAPO; SPAZI(1);
  226.  
  227.     ImpostaColoriConsole( GIALLO );
  228.     PAUSE;
  229.     ImpostaColoriConsole( COL_DFLT );
  230. }
  231.  
  232. /*==============================================================================
  233. Predispone la lista dei caratteri compresi tra 0 e 31 (alcuni caratteri
  234. "problematici" vengono omessi).
  235. ==============================================================================*/
  236.  
  237. char *ListaCaratteri_0_31( char *buff ) {
  238.     if( buff != NULL ) {
  239.         char *p = buff;
  240.         int nc;
  241.  
  242.         for( int pc=0, i=0; i<8; ++pc, ++i ) {
  243.             for( int j=0; j<4; ++j ) {
  244.                 nc = pc+8*j;
  245.                 switch( nc ) {
  246.                     case '\0':
  247.                     case 7:
  248.                     case 8:
  249.                     case '\t':
  250.                     case '\n':
  251.                     case '\r':
  252.                         p += sprintf( p, "%4d %c  ", nc, ' ' );
  253.                         break;
  254.                     default:
  255.                         p += sprintf( p, "%4d %c  ", nc, nc );
  256.                 }
  257.             }
  258.             p += sprintf( p, "%s", "\n" );
  259.         }
  260.     }
  261.  
  262.     buff[strlen(buff)-1] = '\0'; // elimina l'ultimo "a capo"
  263.  
  264.     return buff;
  265. }
  266.  
  267. /*==============================================================================
  268. Predispone la lista dei caratteri compresi tra 32 e 127.
  269. ==============================================================================*/
  270.  
  271. char *ListaCaratteri_32_127( char *buff ) {
  272.     if( buff != NULL ) {
  273.         char *p = buff;
  274.  
  275.         for( int pc=32, i=4; i<20; ++pc, ++i ) {
  276.             for( int j=0; j<6; ++j )
  277.                 p += sprintf( p, "%4d %c  ", pc+16*j, pc+16*j );
  278.             p += sprintf( p, "%s", "\n" );
  279.         }
  280.     }
  281.  
  282.     buff[strlen(buff)-1] = '\0'; // elimina l'ultimo "a capo"
  283.  
  284.     return buff;
  285. }
  286.  
  287. /*==============================================================================
  288. Predispone la lista dei caratteri compresi tra 128 e 255.
  289. ==============================================================================*/
  290.  
  291. char *ListaCaratteri_128_255( char *buff ) {
  292.     if( buff != NULL ) {
  293.         char *p = buff;
  294.  
  295.         for( int pc=128, i=0; i<16; ++pc, ++i ) {
  296.             for( int j=0; j<8; ++j )
  297.                 p += sprintf( p, "%4d %c  ", pc+16*j, pc+16*j );
  298.             p += sprintf( p, "%s", "\n" );
  299.         }
  300.     }
  301.  
  302.     buff[strlen(buff)-1] = '\0'; // elimina l'ultimo "a capo"
  303.  
  304.     return buff;
  305. }
  306.  
  307. /*==============================================================================
  308. Centra una stringa di testo nella console.
  309. ==============================================================================*/
  310.  
  311. void Centrato( const char *s, int largh ) {
  312.     int ls = strlen( s );
  313.     SPAZI((largh-ls)/2);
  314.     printf( s );
  315. }
  316.  
  317. /*==============================================================================
  318. Presenta un riquadro contenente una stringa di testo.
  319. ==============================================================================*/
  320.  
  321. void Box( const char *s, int largh, int marg, bool txt_centrato, bool X2 ) {
  322.     const char *p1=s, *p2=s;
  323.     int i, j, ls, nRighe;
  324.  
  325.     if( marg < 0 ) marg = (gColCons-largh)/2;
  326.  
  327.     largh -= 2;
  328.     ls = strlen( s );
  329.  
  330.     for( nRighe=1, i=0; i<ls; ++i ) if( s[i] == '\n' ) ++nRighe;
  331.  
  332.     if( X2 )
  333.         { SPAZI(marg); RIGA_2(largh+2); }
  334.     else { SPAZI(marg); RIGA(largh+2); }
  335.  
  336.     for( i=0; i<nRighe; ++i ) {
  337.         p2 = i<nRighe-1 ? strchr(p1,'\n') : strchr(p1,'\0');
  338.         A_CAPO; SPAZI(marg);
  339.         ls = p2-p1;
  340.         RIGA_VERT;
  341.         if( txt_centrato ) SPAZI( (largh-ls)/2 );
  342.         for( j=0; j<ls; ++j ) printf( "%c", p1[j] );
  343.         if( txt_centrato )
  344.             { SPAZI( (largh-ls)/2+(largh-ls)%2 ); }
  345.         else { SPAZI( largh-ls ); }
  346.         RIGA_VERT;
  347.         p1 = p2+1;
  348.     }
  349.  
  350.     if( X2 )
  351.         { A_CAPO; SPAZI(marg); RIGA_2(largh+2); }
  352.     else { A_CAPO; SPAZI(marg); RIGA(largh+2); }
  353. }
  354.  
  355. /*==============================================================================
  356. Visualizza un messaggio di errore.
  357. ==============================================================================*/
  358.  
  359. void Errore( const char *msg ) {
  360.     ImpostaColoriConsole( ROSSO );
  361.     Box( msg, 60, 10, false, true );
  362.     ImpostaColoriConsole( COL_DFLT );
  363.     A_CAPO; A_CAPO; SPAZI(1); PAUSE;
  364. }