Oppure

Loading
24/01/17 22:14
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

// translation.h
#pragma once

#ifdef ITALIANO 
	#include "it.h"
#elif INGLESE 
	#include "en.h"
#else FRANCESE 
	#include "fr.h"
#endif // altri linugaggi se voglio

//it.h
#pragma once

#define _PRIMO "Primo"
#define _SECONDO "Secondo"
#define _METODO "Metodo"
#define _PRIMO_METODO "Primo Metodo"
#define _SECONDO_METODO "Secondo Metodo"


//main.c
#include <stdio.h>

#define ITALIANO 1

#include "Translation.h"

int main( int argc , char ** argv ) {

	printf( "\n" _PRIMO _METODO );

	return 0;
}



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
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) :
//file.h uguale per ogni lingua
#pragma once

#ifdef TRANSLATION_EXPORTS
#define FUNCSDLL_API __declspec(dllexport) 
#else
#define FUNCSDLL_API __declspec(dllimport) 
#endif

#define _PRIMO 0
#define _SECONDO 1
#define _METODO 2
#define _PRIMO_METODO 3
#define _SECONDO_METODO 4

FUNCSDLL_API char* frasi( int i );

//file.c a seconda della lingua

#include "Intestazione.h"
FUNCSDLL_API char* frasi( int i ) {

	char *stringhe[] =
	{
	"Primo",
	"Secondo",
	"Metodo",
	"Primo Metodo",
	"Secondo Metodo"
	};

	return stringhe[i];
}


Creo la DLL, e poi nel main dei miei progetti:
#include <stdio.h>
#include "Intestazione.h"

int main( int argc , char ** argv ) {
	
	puts(frasi( _PRIMO ));
	puts(frasi( _SECONDO ));
	puts(frasi( _METODO ));
	puts(frasi( _PRIMO_METODO ));
	puts(frasi( _SECONDO_METODO));
	return 0;
}


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 24/01/17 22:15
24/01/17 22:31
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.
aaa
25/01/17 9:16
Template
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:


frase(lingua)
   se lingua == italiano
       ritorna "ciao"
   se invece lingua == inglese
       ritorna "hello"
   ...



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.
aaa
25/01/17 9:44
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.


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 :)


#include <stdio.h>
#include <stdlib.h>
char Lingue[3][2][20]={{"ciao","fine"},{"hello","end"},{"hola","fineSpagnolo"}};
int main(int argc, char *argv[])
{
  int i=0;
  do{
      printf("1 Italiano\n");
      printf("2 Inglese\n");
      printf("3 Spagnolo\n");
      printf ("4 Fine programma\n");
      scanf("%d",&i);
      printf("%s\n",Lingue[i-1][0]);
      printf("%s\n" ,Lingue[i-1][1]);
      
  }while(i!=4);    
  system("PAUSE");	
  return 0;
}




Ultima modifica effettuata da torn24 25/01/17 10:21
aaa
25/01/17 11:22
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:
 if "italiano"
 carica italiano.dll
includi "solo" questo header "english.h"

if "english"
carica english.dll
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:


 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:
// Italiano = 0
 printf ("%s\n", FineProgramma(0)");  //Template , comprensibile
 printf ("%s\n", lingua[0][1] );  // torn24 , ma non mi ricordo la frase che c'è dietro

//VS

 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 25/01/17 11:23
25/01/17 11:47
Template
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:

funzione(language)
   nome = "$language.dat"
   apri il file "nome"
   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 25/01/17 11:49
aaa
25/01/17 15:30
lumo
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: en.wikipedia.org/wiki/…
Per windows: mlocati.github.io/articles/…
Ultima modifica effettuata da lumo 25/01/17 15:32
aaa
25/01/17 15:38
lumo
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.
aaa