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++ - [c]-Programma multilingua
Forum - C/C++ - [c]-Programma multilingua

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 1:00
Giovedì, 01/01/1970
Buon sera a tutti. Vi espongo subito il quesito:
Mi piacerebbe immettere la possibilità di scegliere la lingua nei miei applicativi. (Da input se possibile)
Sono riuscito a cambiare lingua tramite #define

Codice sorgente - presumibilmente C++

  1. // translation.h
  2. #pragma once
  3.  
  4. #ifdef ITALIANO
  5.         #include "it.h"
  6. #elif INGLESE
  7.         #include "en.h"
  8. #else FRANCESE
  9.         #include "fr.h"
  10. #endif // altri linugaggi se voglio
  11.  
  12. //it.h
  13. #pragma once
  14.  
  15. #define _PRIMO "Primo"
  16. #define _SECONDO "Secondo"
  17. #define _METODO "Metodo"
  18. #define _PRIMO_METODO "Primo Metodo"
  19. #define _SECONDO_METODO "Secondo Metodo"
  20.  
  21.  
  22. //main.c
  23. #include <stdio.h>
  24.  
  25. #define ITALIANO 1
  26.  
  27. #include "Translation.h"
  28.  
  29. int main( int argc , char ** argv ) {
  30.  
  31.         printf( "\n" _PRIMO _METODO );
  32.  
  33.         return 0;
  34. }



Ometto le ltre lingue per brevità, ma sono tutte strutturate come it.h

In questo modo ho 1 header per ogni linuga, nel main() posso mettere
Codice sorgente - presumibilmente Plain Text

  1. printf("%s",_YES);


cosi da capire ugualmente la stringa. Però devo ricompilare ogni volta che voglio cambiare lingua.

il secodo metodo (uso di una DLL) :
Codice sorgente - presumibilmente C++

  1. //file.h uguale per ogni lingua
  2. #pragma once
  3.  
  4. #ifdef TRANSLATION_EXPORTS
  5. #define FUNCSDLL_API __declspec(dllexport)
  6. #else
  7. #define FUNCSDLL_API __declspec(dllimport)
  8. #endif
  9.  
  10. #define _PRIMO 0
  11. #define _SECONDO 1
  12. #define _METODO 2
  13. #define _PRIMO_METODO 3
  14. #define _SECONDO_METODO 4
  15.  
  16. FUNCSDLL_API char* frasi( int i );
  17.  
  18. //file.c a seconda della lingua
  19.  
  20. #include "Intestazione.h"
  21. FUNCSDLL_API char* frasi( int i ) {
  22.  
  23.         char *stringhe[] =
  24.         {
  25.         "Primo",
  26.         "Secondo",
  27.         "Metodo",
  28.         "Primo Metodo",
  29.         "Secondo Metodo"
  30.         };
  31.  
  32.         return stringhe[i];
  33. }



Creo la DLL, e poi nel main dei miei progetti:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include "Intestazione.h"
  3.  
  4. int main( int argc , char ** argv ) {
  5.        
  6.         puts(frasi( _PRIMO ));
  7.         puts(frasi( _SECONDO ));
  8.         puts(frasi( _METODO ));
  9.         puts(frasi( _PRIMO_METODO ));
  10.         puts(frasi( _SECONDO_METODO));
  11.         return 0;
  12. }



Qui ho il vantaggio che posso caricare qualsiasi lingua sostituendo la DLL, ma ogni DLL deve avere lo stesso nome delll'altra e non posso modificarlo a programma partito.

Mi chiedevo se ci fossero metodi per il C miglior dei due postati o se si potesse scegliere la lingua via console a programma avviato (magari scegliendo la DLL da caricare avendole tutte nella cartella dell'eseguibile).

Grazie a tutti per le risposte.





Ultima modifica effettuata da il 24/01/2017 alle 23:15
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 23:31
Martedì, 24/01/2017
Per cercare in rete questo problema usa "internationalization" o di solito abbreviato con "i18n"

I programmi che esistono non fanno molto di diverso da quello che fai tu, io so all'incirca come fare usando GNU gettext che però è sotto licenza GPL.
Visto che sei su windows potresti guardare cosa offre microsoft, su MSDN c'è molta roba su localization e internationalization.

PM Quote
Avatar
Template (Member)
Pro


Messaggi: 177
Iscritto: 09/12/2015

Segnala al moderatore
Postato alle 10:16
Mercoledì, 25/01/2017
Banalmente, potresti creare una libreria con una funzione per frase, che dato un parametro che identifichi la lingua ritorni la frase opportuna. Una cosa del genere:


Codice sorgente - presumibilmente Plain Text

  1. frase(lingua)
  2.    se lingua == italiano
  3.        ritorna "ciao"
  4.    se invece lingua == inglese
  5.        ritorna "hello"
  6.    ...




Anche decidessi di fare così, comunque, potresti fare lo stesso la ricerca proposta da Lumo, se non altro per sapere come viene fatto normalmente e cosa i vari ambienti offrono in tal senso.

PM Quote
Avatar
torn24 (Normal User)
Pro


Messaggi: 156
Iscritto: 04/01/2008

Segnala al moderatore
Postato alle 10:44
Mercoledì, 25/01/2017
Vorrei proporre un idea non professionale ma alquanto semplice, sperando che non mi uccidano per la cosa "siate buoni" :rotfl:



Pensavo di usare un array tridimensionale di char, la prima dimensione è la lingua, la seconda sono le parole. In questo modo
si fa scegliere all'utente la lingua, e si stampa il contenuto della matrice come output.


Esempio, cosi funziona, ma francamente non so il perché, non so come sono organizzate in memoria gli array tridimensionali, ed è
la prima volta che li uso :)

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. char Lingue[3][2][20]={{"ciao","fine"},{"hello","end"},{"hola","fineSpagnolo"}};
  4. int main(int argc, char *argv[])
  5. {
  6.   int i=0;
  7.   do{
  8.       printf("1 Italiano\n");
  9.       printf("2 Inglese\n");
  10.       printf("3 Spagnolo\n");
  11.       printf ("4 Fine programma\n");
  12.       scanf("%d",&i);
  13.       printf("%s\n",Lingue[i-1][0]);
  14.       printf("%s\n" ,Lingue[i-1][1]);
  15.      
  16.   }while(i!=4);    
  17.   system("PAUSE");     
  18.   return 0;
  19. }




Ultima modifica effettuata da torn24 il 25/01/2017 alle 11:21
PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 12:22
Mercoledì, 25/01/2017
Testo quotato

Postato originariamente da lumo:

Per cercare in rete questo problema usa "internationalization" o di solito abbreviato con "i18n"

I programmi che esistono non fanno molto di diverso da quello che fai tu, io so all'incirca come fare usando GNU gettext che però è sotto licenza GPL.
Visto che sei su windows potresti guardare cosa offre microsoft, su MSDN c'è molta roba su localization e internationalization.



Grazie della risposta. Su MSDN ho trovato roba che però usa MFC e C++/C#, e su internet esempi che usano file di risorse scritti in Visual Basic.
Vorrei un modo ad esempio:
Codice sorgente - presumibilmente C/C++

  1. if "italiano"
  2.  carica italiano.dll
  3. includi "solo" questo header "english.h"
  4.  
  5. if "english"
  6. carica english.dll
  7. includi "solo" questo header "english.h"



@Template[grazie pure a te per l'apporto al topic],
si ci avevo pensato, ma se volessi aggiungere una lingua mi tocca cambiare tutte le funzioni e diventerebbe un lavoraccio, inoltre avrei lo stesso problema della soluzione di @torn24[grazie anche a te] .(p.s. io avevo anche pensato ad una struct di stringhe invece che array tridimensionale, da quel che so è un pò più performante)
Il problema e', ad esempio:

Codice sorgente - presumibilmente Plain Text

  1. printf ("4 Fine programma\n");



Lasciando perdene nel sorgente che lo vedrei solo io.. ma nella console, qualsiasi lingua impostata uscirebbe una scritta in italiano Per fare in modo che le scritte siano nella lingua esatta dovrei mettere:
Codice sorgente - presumibilmente Plain Text

  1. // Italiano = 0
  2.  printf ("%s\n", FineProgramma(0)");  //Template , comprensibile
  3.  printf ("%s\n", lingua[0][1] );  // torn24 , ma non mi ricordo la frase che c'è dietro
  4.  
  5. //VS
  6.  
  7.  printf ("%s\n", __FineProgramma"); //mia idea


Anche come prestazioni, l'impatto di dover chiamare una funzione per ogni stringa, non è eccessivo rispetto ad una semplice #define?

P.S.    O.T. ma come posso vedere l'anteprima dei messagi che scrivo per controllarli?



Ultima modifica effettuata da il 25/01/2017 alle 12:23
PM Quote
Avatar
Template (Member)
Pro


Messaggi: 177
Iscritto: 09/12/2015

Segnala al moderatore
Postato alle 12:47
Mercoledì, 25/01/2017
Testo quotato

Postato originariamente da Mikelius:
@Template[grazie pure a te per l'apporto al topic],
si ci avevo pensato, ma se volessi aggiungere una lingua mi tocca cambiare tutte le funzioni e diventerebbe un lavoraccio
[...]
Anche come prestazioni, l'impatto di dover chiamare una funzione per ogni stringa, non è eccessivo rispetto ad una semplice #define?



Rispondo a tutti e due i quesiti contemporaneamente:

Molto dipende dal design delle tue librerie: se le strutturi basandoti su più database (uno per lingua) avente per nome il contenuto della variabile "language" che passeresti alla tua funzione, ti basta scrivere le varie funzioni come:

Codice sorgente - presumibilmente C/C++

  1. funzione(language)
  2.    nome = "$language.dat"
  3.    apri il file "nome"
  4.    reperisci la riga che ti serve



Addirittura, se alla funzione dai un secondo parametro che identifichi la riga che ti serve (potresti definire delle macro per questo), puoi realizzare una sola funzione per reperire qualsiasi riga.

Ancora: puoi definire una seconda funzione cui passare, all'avvio del programma, la variabile "language", in modo da poter caricare subito il database che ti serve (in una tabella di simboli, per esempio) e poter migliorare la gestione della funzione di "ritorno parola"... in questo modo, se sei un programmatore "furbo", puoi migliorare decisamente le prestazioni della tua funzione.

E non finisce qui: se oltre che "furbo" sei anche bravo, non è escluso che tu riesca ad implementare gran parte di queste cose usando delle macro, ottenendo così ciò che volevi all'inizio :k:

Ultima modifica effettuata da Template il 25/01/2017 alle 12:49
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 16:30
Mercoledì, 25/01/2017
Per Windows i resource file funzionano anche su C/C++ usando visual studio, in ogni caso ho letto meglio e la licenza di gettext è LGPL per il runtime, quindi se fai link dinamico della libreria (leggi: dll) puoi usarla anche in un progetto closed source, a patto che non modifichi gettext.

Su Wikipedia trovi un riassunto su come funziona: https://en.wikipedia.org/wiki/Gettext
Per windows: https://mlocati.github.io/articles/gettext-iconv-windows.html

Ultima modifica effettuata da lumo il 25/01/2017 alle 16:32
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 16:38
Mercoledì, 25/01/2017
Testo quotato

Postato originariamente da torn24:

Vorrei proporre un idea non professionale ma alquanto semplice, sperando che non mi uccidano per la cosa "siate buoni" :rotfl:



Pensavo di usare un array tridimensionale di char, la prima dimensione è la lingua, la seconda sono le parole. In questo modo
si fa scegliere all'utente la lingua, e si stampa il contenuto della matrice come output.



Ovviamente si possono avere soluzioni artigianali a volontà :rotfl: solo che con il tuo metodo hai svariati problemi:
1) devi ricompilare il programma ogni volta
2) devi modificare quell'array tridimensionale a mano, compreso aumentare la terza dimensione se hai stringhe che diventano più lunghe di quelle che avevi già, insomma è facile fare errore e sbagliare.
3) il problema maggiore è che dentro il programma userai indici, quindi devi ogni volta andare a controllare a quale indice corrisponde la stringa che vuoi, invece se guardi gettext ti basta mettere la stringa dentro un gettext() e dopo i file verranno processati in quei punti in modo da far sì che quella stringa venga cambiata a seconda del linguaggio (e lì effettivamente viene fuori un indice numerico, quindi non lontano dalla tua idea). Questo permette di far sì che le stringhe siano ancora esplicite e comprensibili.

PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 21:08
Mercoledì, 25/01/2017
Sto cercando di capire come usare la gettex per windows...

ad esempio non trovo

libintl.h
e cmq non è affatta semplicissimo usarla

PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo