PDA

Visualizza la versione completa : [C] Controllo dell'input nel programma


plaztinum
19-02-2018, 22:25
Buongiorno/buonasera.

Sto scrivendo una text-based adventure per hobby. Il programma sembra funzionare bene, se non per alcuni fattori:

1) quando premo 2 (credits) e premo 'b' per ritornare al menù, quando premo il tasto 3 (exit), rimane bloccato in un loop.

2) ci sono dei messaggi del compilatore che non ho ben capito come risolvere

qui di seguito posto il codice e i messaggi usciti:



#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#define MAX_LEN 128


void red(){
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
int k;
SetConsoleTextAttribute(hConsole, k=12);
}

void white(){
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
int l;
SetConsoleTextAttribute(hConsole, l=15);
}

void green(){
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
int a;
SetConsoleTextAttribute(hConsole, a=10);
}

int image(){

char *filename = "drago.txt";
FILE *fptr = NULL;

if((fptr = fopen(filename,"r")) == NULL)
{
fprintf(stderr,"error opening %s\n",filename);
return 1;
}

print_image(fptr);
}

void submenu2(void){
for(;;){
char choice1;
system("cls");
printf("Written by Francesco\nIDE: Bloodshed Dev-C++\nProgrammed in C\nFebruary 2018\n");
printf("Press b key to come back to menu...\n>>");
scanf("%c",&choice1);

if(choice1 == 'b'){
system("cls");
//image();
menu();
break;} // torna al mainmenu
else
printf("wrong input. try again.");
}
}


void menu(){
int choice,i=1;
image();
red();
printf("\n\t\t\tSoftware version 1.0 Beta");
green();
printf("\t\t\t All rights reserved 2018\n\n");

white();
printf("[1] Play\n");
printf("[2] Credits\n");
printf("[3] Exit\n>>");

while(i){
scanf("%d",&choice);

switch(choice){
case 1:
break;

case 2:
submenu2();
break;

case 3:
system("cls");
green(); printf("\n\t\t\t\t\t ***************************************\n ");
red();printf("\n\t\t\t\t ***********Thanks for playing**********\n");
white();printf("\n\t\t\t\t\t ***************************************\n ");
i = 0; /* loop exit */
break;

default:
printf("\nInvalid choice!\n>>");
break;

}
}
return 0;
}


void print_image(FILE *fptr);


int main(void)
{
menu();
return 0;
}


void print_image(FILE *fptr)
{
char read_string[MAX_LEN];

while(fgets(read_string,sizeof(read_string),fptr) != NULL)
printf("%s\t\t\t\t",read_string);
}


messaggi di errore:
2926729269

PS: vorrei implementare un modo per controllare l'input quando viene digitato un carattere al posto del numero, sapreste suggerirmi come fare?

Grazie a chiunque risponderà

paolino_delta_t
20-02-2018, 15:57
Quelli non sono errori, sono dei warning. Il compilatore ti dice che non stai facendo le cose a regola d'arte.

Innanzitutto definisce la funzione menu come void e poi ritorni 0? Ma le funzioni void non ritornano niente.

Gli altri due riguardano il punto in cui le funzioni sono definite. In image invochi print_image prima che sia stata definita. In genere non si fa così.

La linea


void print_image(FILE *fptr);

va messa prima delle prima chiamata alla funzione. Oppure, come si fa in C, in un file header ( .h ) apposito.

Stesso discorso per menu, che viene invocata in submenu2 prima di essere dichiarata o definita.

Se vuoi farla semplice, sposta l'ordine delle funzioni e vedrai che quei warning spariranno.

Riguardo il problema 1, è una questione di logica. Stai nel loop di menu, se premi 2 chiami submenu2, da cui chiami di nuovo menu se premi b. Ma la seconda chiamata avvia un nuovo loop di menu. Quindi quando premi 3 esci dal secondo loop, premendo di nuovo 3 uscirai dal primo loop e il programma terminerà.

Ovviamente c'è un errore logico dietro, perchè il programma non deve funzionare così. In submenu2 devi semplice ritornare e non richiamare menu. Se vuoi rivisualizzare le tre voci del menu, o lo fai nel secondo case del menu ( a questo punto ti conviene un'altra funzione che si occupa solo di visualizzare il menu a schermo ) o lo fai in submenu2 ( magari chiamando sempre questa nuova funzione creata apposta ).

plaztinum
24-02-2018, 21:16
paolino_delta_t (http://forum.html.it/forum/member.php?userid=88576) Mi scuso per il ritardo nel risponderti. Comunque grazie al tuo aiuto ho risolto, grazie mille! Qui di seguito ti lascio nuovamente il codice così (forse un pò per curiosità :rolleyes:), potrai vedere le mie modifiche e magari darmi altri suggerimenti.


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#define MAX_LEN 128


void red(){
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
int k;
SetConsoleTextAttribute(hConsole, k=12);
}

void white(){
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
int l;
SetConsoleTextAttribute(hConsole, l=15);
}

void green(){
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
int a;
SetConsoleTextAttribute(hConsole, a=10);
}

void submenu2(void);
void print_image(FILE *fptr);
void menu();
void main_menu();

int image(){

char *filename = "drago.txt";
FILE *fptr = NULL;

if((fptr = fopen(filename,"r")) == NULL)
{
fprintf(stderr,"error opening %s\n",filename);
return 1;
}

print_image(fptr);
}

void main_menu(){
image();
red();
printf("\n\t\t\tSoftware version 1.0 Beta");
green();
printf("\t\t\t All rights reserved 2018\n\n");

white();
printf("[1] Play\n");
printf("[2] Credits\n");
printf("[3] Exit\n>>");
}

void submenu2(void){
for(;;){
char choice1;
system("cls");
printf("Written by Francesco\nIDE: Bloodshed Dev-C++\nProgrammed in C\nFebruary 2018\n");
printf("Press b key to come back to menu...\n>>");
scanf("%c",&choice1);

if(choice1 == 'b'){
system("cls");
main_menu();
break;} // torna al mainmenu
else
printf("wrong input. try again.");
}
}


void menu(){
int choice,i=1;
image();
main_menu();

while(i){
scanf("%d",&choice);

switch(choice){
case 1:
break;

case 2:
submenu2();
break;

case 3:
system("cls");
green(); printf("\n\t\t\t\t\t ***************************************\n ");
red();printf("\n\t\t\t\t ***********Thanks for playing**********\n");
white();printf("\n\t\t\t\t\t ***************************************\n ");
i = 0; /* loop exit */
break;

default:
printf("\nInvalid choice!\n>>");
break;

}
}
}

int main(void)
{
menu();
return 0;
}


void print_image(FILE *fptr)
{
char read_string[MAX_LEN];

while(fgets(read_string,sizeof(read_string),fptr) != NULL)
printf("%s\t\t\t\t",read_string);
}


Comunque ho cercato un pò sul web su come effettuare un controllo dell'input di un carattere al posto di un numero, però non sono riuscito a giungere a capo. Suggerimenti?

paolino_delta_t
25-02-2018, 11:06
Perchè cos'ha scanf che non va?

plaztinum
25-02-2018, 12:49
Funziona come previsto, ma il problema è che se inserisco un carattere al posto di un numero, questo entra in un loop infinito. Quindi vorrei anche correggere l'errato inserimento di un carattere al posto di un numero.

paolino_delta_t
26-02-2018, 11:33
Funziona come previsto, ma il problema è che se inserisco un carattere al posto di un numero, questo entra in un loop infinito. Quindi vorrei anche correggere l'errato inserimento di un carattere al posto di un numero.In questo caso devi leggere anche i numeri usando il %c, cioè leggerli come caratteri. Ovviamente lo switch case va modificato opportunamente, cioè tipo case '1': ecc....

plaztinum
26-02-2018, 19:40
Ok ora va già meglio. Avevo riscontrato un piccolo problema nel ritornare al menù principale dopo essere uscito dal case '2' (mi stampava in automatico qualcosa e mi usciva 'Invalid choice'), ma ho ovviato svuotando il buffer di tastiera. Non so come ringraziarti, credo che ti menzionerò nei crediti (a patto che tu sia d'accordo :stordita:)

paolino_delta_t
27-02-2018, 15:25
Ok ora va già meglio. Avevo riscontrato un piccolo problema nel ritornare al menù principale dopo essere uscito dal case '2' (mi stampava in automatico qualcosa e mi usciva 'Invalid choice'), ma ho ovviato svuotando il buffer di tastiera. Non so come ringraziarti, credo che ti menzionerò nei crediti (a patto che tu sia d'accordo :stordita:)

Perfetto. Un consiglio generale che posso darti. Impara a simulare il codice man mano che lo scrivi, nella tua testa. Lo so richiede uno sforzo iniziale notevole, ma riuscirai a scrivere pezzi ( piccoli, per quelli grandi ci sono tecniche di ingegneria del software ) di codice che al 99% saranno corretti. Accoppiato a tecniche e linguaggi di programmazione funzionale, riuscirai a scrivere software robusto ed efficiente con naturalezza.

Loading