Programma per apprendere il vocabolario inglese!

di il
11 risposte

Programma per apprendere il vocabolario inglese!

Desideravo creare un programmino capace di interrogare l'utente su quanti vocaboli quest'ultimo desidera, dall'inglese all'italiano o dall'italiano all'inglese indifferentemente. Se l'utente fornisce la traduzione corretta, bene, altrimenti il programma lo correggerà fornendogli la traduzione.

Compilo con WxDev-c++, e tale compilatore non mi segnala errori nel codice eppure l'esecuzione salta ogni volta che inserisco la prima traduzione e premo invio.

Non escludo errori grossolani.

Il codice è questo:

#include<stdlib.h>
#include<iostream>

using namespace std;


main()

{
srand(time(NULL));
int n;

char* E[10]={"home","book","yesterday","scary","biscuit","brillant","cheese","full","garage","drink"};
char* I[10]={"casa","libro","ieri","pauroso","biscotto","brillante","formaggio","pieno","benzinaio","bere"};

cout<<"Su quante parole vuoi essere interrogato?"<<endl; //Il ciclo for muoverà proprio n passi
cin>>n;
cout<<endl;

for(int i=0;i<n;i++)
{
int c=rand()%10;
int d=rand()%2;
char* t[]={"change"};

char* b=E[c];
char* k=I[c];

if(d==0)
{
cout<<E[c]<<endl;
cout<<"Traduzione: ";
char* a=t[0];
cin>>a;

if(a=k)
cout<<"Esatto!"<<endl<<endl;
if(a!=k)
cout<<"Sbagliato! La traduzione corretta e': "<<I[c]<<endl<<endl;
}

if(d==1)
{
cout<<I[c]<<endl;
cout<<"Traduzione: ";
char* a=t[0];
cin>>a;


if(a=b)
cout<<"Esatto!"<<endl<<endl;
if(a!=b)
cout<<"Sbagliato! La traduzione corretta e': "<<E[c]<<endl<<endl;
}

}

system("pause");
}

11 Risposte

  • Re: Programma per apprendere il vocabolario inglese!

    Ciao,
    per ora ho dato un'occhiata solo sommaria al codice e posso darti un paio di consigli, non risolveranno il tuo problema ma possono aiutare te e altri a farlo
    Usa i tag [/code] per racchiudere il codice, migliora la leggibilità e si riesce anche a capire com'è fatta l'indentazione.
    Cerca di usare nomi di variabili che rendono l'idea di cosa rappresentano: usando c,b,t,k,d si capisce poco se lo si legge dall'esterno ed è difficoltoso (almeno per me ) seguire il filo logico del programma. Magari adesso ti sembra di capirle, ma se dovrai riprendere in mano il programma fra un paio d'anni ti garantisco che non sarà così facile ricordarti a cosa corrisponde la singola lettera. Basterebbe ad esempio indicare i vettori anzichè con E e I come eng, ita e già migliora la comprensione (non so b, c, t, cosa rappresentino).

    Veniamo alle cose utili:
    -se stai usando il c++, per fare un programma di questo tipo ti converrebbe di gran lunga usare, anzichè i vettori di char, vettori di string. E' molto più facile confrontare due stringhe che non due vettori di char. Il problema potrebbe essere proprio nel confronto tra le due stringhe, è lì che va in crash, no? Che problema hai, segmentation fault?
  • Re: Programma per apprendere il vocabolario inglese!

    Ciao, così funziona.
    
    #include <stdlib.h>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    
    main()
    
    {
    srand(time(NULL));
    int n;
    
    string E[10]={"home","book","yesterday","scary","biscuit","brillant","cheese","full","garage","drink"};
    string I[10]={"casa","libro","ieri","pauroso","biscotto","brillante","formaggio","pieno","benzinaio","bere"};
    
    cout<<"Su quante parole vuoi essere interrogato?"<<endl; //Il ciclo for muoverà proprio n passi
    cin>>n;
    cout<<endl;
    
    for(int i=0;i<n;i++)
    {
    	int c=rand()%10;
    	int d=rand()%2;
    	string answer;
    
    	string english=E[c];
    	string italian=I[c];
    
    	if(d==0)
    	{
    		cout<<E[c]<<endl;
    		cout<<"Traduzione: ";
    		cin>>answer;
    
    		if(answer==italian)	cout<<"Esatto!"<<endl<<endl;
    		if(answer!=italian) cout<<"Sbagliato! La traduzione corretta e': "<<I[c]<<endl<<endl;
    	}
    
    	if(d==1)
    	{
    		cout<<I[c]<<endl;
    		cout<<"Traduzione: ";
    		cin>>answer;
    
    		if(answer==english) cout<<"Esatto!"<<endl<<endl;
    		if(answer!=english) cout<<"Sbagliato! La traduzione corretta e': "<<E[c]<<endl<<endl;
    	}	
    
    }
    
    //system("pause");
    return 0;
    }
    
    
    
    Ho sostituito i vettori di char con delle stringhe (se non ricordo male, se usi i char per confrontarli devi usare la funzione strcmp()), c'era un errore nel confronto delle stringhe in quanto avevi scritto
    a=k
    al posto di
    a==k
    (resta il fatto che, ripeto, a memoria con i vettori di char non si può fare un'operazione di confronto così, questa va bene per le string). Ho commentato il system("pause") perchè non ho capito cosa volevi fare, ho invece aggiunto return 0;.

    L'ho provato e funziona. Se volessi aggiungere altre parole potresti pensare di usare dei vector, oppure potresti introdurre un #define N per il numero dei posti del vettore, insomma, se e quando avrai intenzione di espanderlo di robe da fare ne hai

    Se hai domande chiedi pure, se sono in grado rispondo!
  • Re: Programma per apprendere il vocabolario inglese!

    Cavoli, grazie mille eugen!
    Sei stato utilissimo, ora mi vedo bene il programma e se mi verranno ulteriori questioni sarò felice di proportele. Però colgo subito l'occasione per chiarirmi una questione, giacché l'hai tirata in ballo: il system("pause")!

    Cosa significa?
    Dunque, se programmo su windows, quando eseguo un qualunque programma (almeno utilizzando come compilatore wxDev-C++, per gli altri non so come sia la faccenda) questo va in esecuzione, ma la finestra si chiude all'istante. Il system("pause") è indispensabile perché stia aperta. Come diavolo fate voialtri a programmare senza metterlo?

    Il return 0; è un'altra bella questione.
    Perché devo necessariamente metterlo? A me i programmi girano benissimo senza Poi ho già visto vagabondando sul web che lo mettono tutti, ma: perché?

    Grazie sin d'ora!
  • Re: Programma per apprendere il vocabolario inglese!

    Ho visto il programma, l'ho capito, solo non mi torna una cosa.

    Hai sostituito char con string, string cos'è tecnicamente? Un tipo? Una funzione implementata con la libreria #include <string>? Perché non compare in grassetto come quando scrivo int o quelle cose lì? Perdona l'ignoranza
  • Re: Programma per apprendere il vocabolario inglese!

    String è un tipo di dato del c++. E' una stringa nel vero senso del termine, non come i vettori di char mutuati dal C (e quindi 'deprecated' nel C++). Il contenuto della classe string lo trovi qui: http://www.cplusplus.com/reference/string

    In breve, le differenze sono queste. Una volta che hai dichiarato un tipo di dato string, non hai bisogno di controllare che ci sia spazio abbastanza per contenere la parola (te lo crea lui), se hai un vettore di char devi star attento a non andare in overflow (ovvero inserire più char dei posti del vettore).
    Se devi confrontare 2 vettori di char, devi usare funzioni del C come strcmp(), se devi aggiungere una stringa ad un'altra devi usare un'altra funzione, utilizzando le string puoi semplicemente usare == se devi confrontare (e questo è stato fatto nella versione che ti ho dato del tuo programma), se devi aggiungere una stringa ad un'altra puoi fare
    string=string1+string2
    e cose così.

    Sono più comode e si incappa molto meno in errori, un elenco completo delle funzioni lo trovi sulla reference del sito cpluplus.com (ad es. le funzioni per vedere quanto è lunga una string).
    Non vorrei venir ammonito per spam, ti mando via mp un link con una lezione breve ma buona sulle string

    Se hai altri dubbi son qui!
  • Re: Programma per apprendere il vocabolario inglese!

    Il programma, ora, risulta così:

    #include <stdlib.h>
    #include <iostream>
    #include <string>

    using namespace std;


    main()

    {
    srand(time(NULL));
    int n;

    string Eng[10]={"home","book","yesterday","scary","biscuit","brillant","cheese","full","garage","drink"};
    string Ita[10]={"casa","libro","ieri","pauroso","biscotto","brillante","formaggio","pieno","benzinaio","bere"};

    cout<<"Su quante parole vuoi essere interrogato?"<<endl; //Il ciclo for muoverà proprio n passi
    cin>>n;
    cout<<endl;

    for(int i=0;i<n;i++)
    {
    int parola=rand()%10;
    int lingua=rand()%2;
    string answer;

    string english=Eng[parola];
    string italian=Ita[parola];

    if(lingua==0)
    {
    cout<<Eng[parola]<<endl;
    cout<<"Traduzione: ";
    cin>>answer;

    if(answer==italian) cout<<"Esatto!"<<endl<<endl;
    if(answer!=italian) cout<<"Sbagliato! La traduzione corretta e': "<<Ita[parola]<<endl<<endl;
    }

    if(lingua==1)
    {
    cout<<Ita[parola]<<endl;
    cout<<"Traduzione: ";
    cin>>answer;

    if(answer==english) cout<<"Esatto!"<<endl<<endl;
    if(answer!=english) cout<<"Sbagliato! La traduzione corretta e': "<<Eng[parola]<<endl<<endl;
    }

    }

    //system("pause");
    return 0;
    }

    E gira bene

    Però mi piacerebbe arricchirlo: certamente è possibile far sì che al termine dell' "interrogazione", ti chieda nuovamente le parole che hai sbagliato. Sarebbe utile per memorizzare tali parole. Però non mi riesce di implementare tale funzione, come posso fare?
  • Re: Programma per apprendere il vocabolario inglese!

    Ciao!
    Per favore, per migliorare la leggibilità del codice puoi usare i tag [/code]? Li trovi sotto la finestra dove scrivi il titolo della discussione
    Adesso rispondo velocemente (non sono sul mio computer), poi proverò appena possibile a buttare giù una riga di codice: potresti ad esempio creare un altro vettore dove memorizzi la posizione delle parole sbagliate, poi quando hai finito di provare tutte le parole lo leggi e passi il contenuto delle celle di memoria del vettore "parole sbagliate" al vettore Eng o Ita. Spero sia chiaro, è più difficile a dirsi che a farsi
    Se hai voglia/tempo e vedi che tardo un po' a rispondere, puoi provare a buttar giù due righe e postarle così quando entro le leggo (magari già riesci a farlo funzionare). Io penso di riuscire a entrare per domani in serata.

    Ps: come ti trovi con le std::string? Un altro "tip": se dovessi riuscire a far funzionare tutto, visto che il programma potrebbe dover contenere un elevato numero di parole (che tra l'altro non si conosce a priori) sarebbe interessante usare uno std::vector...

  • Re: Programma per apprendere il vocabolario inglese!

    L'intento, forse non l'ho chiarito bene, è: che il programma ridomandi le parole sbagliate, e se vi sono altri errori interroghi nuovamente, quella che penso si chiami "ricorsione"
  • Re: Programma per apprendere il vocabolario inglese!

    Avevo capito, tranquillo, ho tardato a rispondere perchè non ero in casa

    Qua c'è una bozza di codice:
    
    #include <stdlib.h>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    
    main()
    
    {
    srand(time(NULL));
    int n;
    int counter=0;
    
    string answer;
    
    string Eng[10]={"home","book","yesterday","scary","biscuit","brillant","cheese","full","garage","drink"};
    string Ita[10]={"casa","libro","ieri","pauroso","biscotto","brillante","formaggio","pieno","benzinaio","bere"};
    
    int sbagli[10];
    
    cout<<"Su quante parole vuoi essere interrogato?"<<endl; //Il ciclo for muoverà proprio n passi
    cin>>n;
    cout<<endl;
    
    for(int i=0;i<n;i++)
    {
    	int parola=rand()%10;
    	int lingua=rand()%2;
    
    	string english=Eng[parola];
    	string italian=Ita[parola];
    
    	if(lingua==0)
    	{
    		cout<<Eng[parola]<<endl;
    		cout<<"Traduzione: ";
    		cin>>answer;
    
    		if(answer==italian) cout<<"Esatto!"<<endl<<endl;
    		if(answer!=italian)
    		{
    			cout<<"Sbagliato! La traduzione corretta e': "<<Ita[parola]<<endl<<endl;
    			sbagli[counter]=parola;
    			++counter;
    		}
    
    	}	
    
    	if(lingua==1)
    	{
    		cout<<Ita[parola]<<endl;
    		cout<<"Traduzione: ";
    		cin>>answer;
    
    		if(answer==english) cout<<"Esatto!"<<endl<<endl;
    		if(answer!=english)
    		{
    			cout<<"Sbagliato! La traduzione corretta e': "<<Eng[parola]<<endl<<endl;
    			sbagli[counter]=parola;
    			++counter;
    		}
    	}
    
    }
    
    cout <<"Ora ti interrogo sulle parole che hai sbagliato" <<endl;
    
    for (int temp=0; temp<counter; temp++){
    	int parola=sbagli[temp];
    	string english=Eng[parola];
    	cout<<Ita[parola]<<endl;
    	cout<<"Traduzione: ";
    	cin>>answer;
    	if(answer==english) cout<<"Esatto!"<<endl<<endl;
    	else cout <<"Studia di più! Hai sbagliato per la seconda volta!" <<endl;
    }
    
    return 0;
    }
    
    
    Bozza nel senso che funziona, anche se ci sono moolti punti in cui può (e dovrebbe essere migliorato). Io mi son limitato a farti vedere la versione funzionante e il modo in cui si risolve il problema, tu poi ti puoi sbizzarrire nel mettere a posto il resto!
    Come vedi, ho creato un altro vettore dove vado a memorizzare il posto della parola sbagliata: quando poi me le ha provate tutte, va a vedere nel vettore sbagli la posizione delle parole sbagliate e richiede quelle. Fin qua abbastanza semplice.
    Io te l'ho fatto solo in una lingua, nell'altro caso è identico.
    Se ti va adesso ti do un paio di consigli su quello che secondo me sarebbe da cambiare, e un'idea di come lo farei io (che poi manco fossi chissà chi, sono un novizio anch'io!):

    - al momento, lui può chiederti parole che ti ha già provato, questo secondo me si può considerare un 'bug' (magari tu l'hai fatto apposta, non lo so)

    - la definizione della dimensione dei vettori mi fa un po' paura: io ho mantenuto il tuo stesso stile per non mandarti in confusione, però sappi che ci possono essere errori, ad es: se vai a modificare la dimensione di un vettore e ti dimentichi degli altri, hai vettori di dimensione diversa (a questo puoi ovviare facendo un #define N all'inizio dove includi le librerie e passando N come dimensione dei vettori). Se inserisci più parole della dimensione del vettore, vai in overflow e non si sa bene cosa succeda nel programma (puoi fare allocazione dinamica della memoria o usare i vector)

    -se vai ad aggiungere molte parole, scriverle esplicitamente nella dichiarazione del vettore rende il codice illeggibile. Perchè non fai in modo che tu salvi le coppie di parole su un file e le carichi nel vettore da lì quando avvii il programma? Così riesci a gestire anche un numero elevato di parole...

    - come sei messo con le classi? Si semplificherebbe notevolemente se cominciassi ad usarle, può sembrare difficile all'inizio poi ti rendi conto che effettivamente son comode.

    Ciao!
  • Re: Programma per apprendere il vocabolario inglese!

    Per prima cosa grazie mille!

    In secondo luogo le tue osservazioni sono tutte quante interessanti e rispondo ad ognuna nell'ordine in cui le hai poste:

    - Può chiedermi due volte le stesse parole, vero. Lo avevo rilevato ed era "in cantiere" di sistemare quel punto.

    - Comprendo e aggiungo #define N.

    - Interessante (nonché indispensabile perché io 'sto programma pensavo di usarlo, non solo di farlo per divertirmi un po' col c++), ma non ho la più pallida idea di come creare un collegamento con un file, sai darmi delle dritte?

    - Sono messo a 0. Letteratura semplice a riguardo?

    Se non sono sempre puntuale nelle risposte o se impiego alcuni giorni a sistemare il codice è perché dedico, purtroppo, a questa attività solo un ritaglio di tempo alla sera quando sono stanco, specie mentalmente.

    Grazie mille ancora della disponibilità, competenza e chiarezza.
  • Re: Programma per apprendere il vocabolario inglese!

    Di niente!

    Ah, ovviamente mi son reso conto che quello che ho scritto prima potrebbe essere frainteso. Il #define si usa nel seguente modo:
    
    #vari include
    #define N 10 //10 è il valore di N
    
    int main(){
    //...
    
    string Eng[N];
    
    //...
    }
    
    In questo modo se vuoi cambiare il numero di posti dei vettori basta che tu cambi il numero associato ad N nel #define e lui lo fa in tutti i vettori che hanno come dimensione N. Occhio però che questo non ti impedisce di inserire più parole dei posti disponibili, devi stare comunque attento.

    - Per quel che riguarda il leggere e scrivere su un file, è praticamente identico al cin/cout. Devi usare (includere) la libreria fstream, qua trovi tutto il contenuto della classe e alcuni esempi.
    http://www.cplusplus.com/reference/iostream/fstream/open/

    Mi ispiro all'esempio della pagina che ti ho linkato per farti vedere una cosa pratica:
    
    #include <fstream>
    #include <string>
    #include <iostream>
    using namespace std;
    
    int main () {
    	string parole;
    	string uscita;
    	fstream nomefile; //Qua stai creando una variabile che si chiama nomefile
    
    //Prima di poter scrivere sul file, devi aprirlo. In pratica, assegni alla variabile nomefile un file reale (che siamo andati a chiamare prova.txt), in questo caso un file di output su cui vai a scrivere. Se il file non esiste viene creato, se esiste già viene aperto e sovrascritto. Con ios::out stai dicendo che è un file di output, se metti ios::in sarà un file di input.
    
    	nomefile.open ("prova.txt",ios::out);
    	
    	cout <<"Scrivi quello che vuoi, questo verrà copiato sul file. Ctrl+D per uscire" <<endl;
    
    	while(!cin.eof()){
    		cin >>parole; //Qua digiti la parola che vuoi
    		uscita=parole; //Qua la assegni a una variabile dello stesso tipo
    		nomefile <<uscita; //Infine dici di salvarla su file: nota l'uso di << come se fosse un cout.
    	}
    
    	nomefile.close(); //Così come all'inizio hai aperto il file, qua lo chiudi
    
      return 0;
    }
    
    Se hai i dati su un file e li vuoi caricare, metti ios::in e al posto di
    cin>>parole;
    scriverai
    nomefile >>parole;
    .

    Comunque sulla reference di cplusplus.com trovi tutte le funzioni che ti possono servire, da quella che ti scrive in cosa a un file già esistente senza cancellarlo, a quella che ti dice se un file esiste o no, etc. etc.

    -Eh, non è facile consigliare qualcosa per partire da 0 con le classi. Sicuramente è molto valido il tutorial che si trova sul solito sito http://www.cplusplus.com/doc/tutorial. Unica cosa è in inglese.
    Se no puoi cominciare a vedere cos'è una funzione in c++, e quando l'hai capito passare allo studio delle classi (prova a fare una ricerca interna al forum, quasi sicuramente è già stato trattato come argomento). In alternativa se cerchi qualcosa con google qualcosa sulle classi trovi, il più è che non so come sia il materiale

    Per adesso comunque cerca di capire queste cose che abbiamo fatto e mettere un po' a posto le cose migliorabili (ad es. il fatto che chieda più volte le parole), questo non dovrebbe richiedere troppo impegno. Quando ti senti sicuro su queste cose (leggere/scrivere su file, utilizzo di stringhe, cicli for, while, if) possiamo fare lo step successivo L'importante è capire poche cose bene.

Devi accedere o registrarti per scrivere nel forum
11 risposte