PDA

Visualizza versione completa : [ansi C] Errore In Gets


krakz
26-02-2003, 12.23.38
/*
Name: CRYDEC TOKI
Author: KRAKZ
Date: 25/02/03 23.08
Description: CRYPTA E DECRYPTA
LICENZA : GNU|GPL
VERSIONE : 1.0
*/

int crypt (void) ;
int decrypt (void) ;




# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# define MAX 255


main ()

{ int I ;
printf (" *** BENVENUTO SU CRYDEC VERSIONE 1.0 ***\n\n\n") ;
printf ("SELEZIONA UNA DELLE OPZIONI\n\n") ;
printf ("1 - Crypta\n") ;
printf ("2 - Decrypta\n") ;
printf ("3 - Info autori\n") ;
printf ("Digita 1, 2 o 3 \n");
scanf ("%d" , &I ) ;

switch(I) {

case 1 : crypt () ;
break ;

case 2 : decrypt () ;
break ;

case 3 : printf ("Krakz") ;
break ;
}
}


int crypt ()
{
int i, I = 0 , countchiave , countfrase , crypt[MAX] ;

char frase[MAX] , chiave[MAX] , nomefile[10] ;

FILE *cfPtr , *apri ;

printf ("Benvenuto su crypt 0.5\n") ;





printf ("Inserisci frase\n") ;
gets(frase) ;
printf ("Inserisci chiave\n") ;
gets(chiave) ;
printf ("Salva con nome\n") ;
gets(nomefile) ;


countfrase = strlen(frase) ; /* VERIFICA LA LUNGHEZZA DELLE STRINGHE */
countchiave = strlen(chiave) ;

for ( i = 0 ; countfrase > i ; i++) /* CONTROLLA CHE TUTTA LA STRINGA SIA CRIPTATA */


{

if ( countchiave < I) I = 0 ;; /* CONTROLLA SE SONO STATE UTILIZZATE TUTTE LE LETTERE DELLA CHIAVE
SE VEDE CHE SONO STATE USATE TUTTE , RESETTA IL TUTTO PARTENDO
DALLA PRIMA LETTERA */

crypt[i] = chiave[I] + frase[i] ; /* CRIPTA LA STRINGA */

if ((cfPtr = fopen( nomefile , "a")) == NULL)

printf("File gia aperto\n");



if ( crypt[i] < 100 ) fprintf(cfPtr, "0" ) ;; /* VERIFICA CHE IL VALORE DATO SIA MAGGIORE DI 100
E SE RISCONTRA UN VALORE MINORE DI 100 AGGIUNGE
IL VALORE 0 */
fprintf(cfPtr, "%d", crypt[i] ); /* STAMPA LA FRASE CRIPTATA */


I = 1 + I ; /* REALIZZA UNO SHIFT A DESTRA */

}

fprintf(cfPtr, "\n\n\nUsa decrypt per vedere il testo\n\n" ) ;
fprintf(cfPtr, "\n\n\nVersione programma 1.0\n\n" ) ;
fprintf(cfPtr, "\n\n\nwww.toki.it\n\n" ) ;
printf ("Il file testo è stato cryptato , per decryptarlo\n") ;

system("PAUSE"); /* COMANDO COMPATIBILE SOLO CON OS WIN , RICHIEDE LA
PRESSIONE DI UN TASTO PER CONTINUARE L'ESECUZIONE
DEL PROGRAMMA*/

}

int decrypt ()
{

int I=0 , i , countfrase , countchiave , dEcrypt[MAX] , de = 0 ;
char frase[MAX] , chiave[MAX] ;



printf ("Inserisci File Cryptato\n") ;
gets(frase) ;
printf ("Inserisci chiave\n") ;
gets(chiave) ;


countfrase = strlen(frase) ;
countchiave = strlen(chiave) ;

for ( i = 0 ; countfrase > i ; i = 3 + i)

{
if ( countchiave < I)
I = 0 ;;

dEcrypt[de] = (frase[i]* 100 + frase [i+1] * 10 + frase [i+2] +48 ) - chiave [I] ;

printf ("%c" , dEcrypt[I]) ;
I = 1 + I ;


}


printf ("\n") ;

system("PAUSE");

}


xke quando seleziono una delle voci 1 o 2
e va nel rispettiva sezione mi salta il primo gets
come faccio ad ovviare a questo problema ???

Crazy Diamond
26-02-2003, 15.46.52
allora....

Come regola generale, non bisognerebbe tentare di alternare chiamate a scanf con chiamate a gets() (o ogni altra routine d'ingresso); il particolare trattamento delle linee nuove scanf porta quasi sempre a problemi. scanf %d non consumera` una linea nuova in fondo. Se il numero in ingresso e`immediatamente seguito da una linea nuova, quella linea nuova soddisfera` immediatamente gets().

Piu` in generale, scanf e` progettato per un ingresso formattato relativamente strutturato, (il suo nome e` infatti derivato da ``scan formatted''). Se si presta attenzione, dice se ha avuto successo o fallito, ma puo` dire solo approssimativamente dove abbia fallito, e per niente come o perche`. E` quasi impossibile fare del recupero di errore decente con scanf; di solito e` di gran lunga piu` facile leggere intere linee (con fgets o simile), poi interpretarle, o usando sscanf o qualche altra tecnica. Inoltre \n in una stringa di formato scanf non significa aspettare una nuova linea, ma piuttosto leggere e scartare caratteri fino a che vi sono caratteri bianchi.

Per quanto riguarda gets() a differenza di fgets(), a gets() non si puo` comunicare la dimensione dello spazio dentro il quale legge, cosi` non gli si puo` impedire di eccedere quello spazio. fgets() invece di gets(), cosi` che la fine del vettore non puo` essere sovrascritta. Sfortunatamente per questo esempio, fgets() non cancella automaticamente il \n finale, come farebbe gets

Questo è stato un cut & paste di varie cose trovate sul web e manualame vario, spero ti possano essere utili....
mi avevi fatto incuriosire :)

buona fortuna :)

krakz
26-02-2003, 22.55.38
ora capisco xke su http://cboard.cprogramming.com/
mi dicono di usare fgets (ma io l'inglese non lo capisco)


cmq fgets da quello che ho capito lo posso usare se ho un file
, ma nel mio caso serve a selezionare un menu composto da 1 2 o 3

LoryOne
27-02-2003, 13.14.23
Davvero molto strano.
Prova ad eliminare il carriage return "\n" dal printf.
Stesso problema ?

P8257 WebMaster
27-02-2003, 18.40.21
Si, questo è uno dei soliti casi in cui il C genera questi problemi di incompatibilità tra routine che svolgono funzioni di lettura, nelle librerie C ne sono implementate un'amiriade, basti solo pensare ai numerosi fratelli di scanf.

Per risolvere il problema, innanzitutto comincerei col sostituire la scanf che legge il valore della selezione, con una ben più stabile getch() (o getche se vuoi fare il perfezionista) che dovrebbe ritornare il valore ascii del carattere premuto consentendoti un metodo di lettura più stabile, poi toglierei i carriage lin-feed come suggerito da Lory, successivamente sostituirei quel "system("PAUSE")" con un bel getch();

Due suggerimenti:
- Il main rigorosamente INT, perché deve passargli l'errorlevel
- Le altre subroutine le vedo meglio void dato che non vi è alcun valore di ritorno.

Bye :cool:

krakz
27-02-2003, 21.26.56
non funziona :eek: :eek: :eek:/*
Name: CRYDEC TOKI
Author: KRAKZ
Date: 25/02/03 23.08
Description: CRYPTA E DECRYPTA
LICENZA : GNU|GPL
VERSIONE : 1.0
*/

int crypt (void) ;
int decrypt (void) ;




# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# define MAX 255


int main ()

{ int I;
printf (" *** BENVENUTO SU CRYDEC VERSIONE 1.0 ***\n\n\n") ;
printf ("SELEZIONA UNA DELLE OPZIONI\n\n") ;
printf ("1 - Crypta\n") ;
printf ("2 - Decrypta\n") ;
printf ("3 - Info autori\n") ;
printf ("Digita 1, 2 o 3 ");
while (( I = getchar ()) != EOF)

{

switch(I) {

case '1': crypt () ;
break ;

case '2': decrypt () ;
break ;

case '3': printf ("Krakz") ;
break ;
}
}
}


int crypt ()
{
int i, I = 0 , countchiave , countfrase , crypt[MAX] ;

char frase[MAX] , chiave[MAX] , nomefile[10] ;

FILE *cfPtr , *apri ;

printf ("Benvenuto su crypt 0.5\n") ;





printf ("Inserisci frase\n") ;
gets(frase) ;
printf ("Inserisci chiave\n") ;
gets(chiave) ;
printf ("Salva con nome\n") ;
gets(nomefile) ;


countfrase = strlen(frase) ; /* VERIFICA LA LUNGHEZZA DELLE STRINGHE */
countchiave = strlen(chiave) ;

for ( i = 0 ; countfrase > i ; i++) /* CONTROLLA CHE TUTTA LA STRINGA SIA CRIPTATA */


{

if ( countchiave < I) I = 0 ;; /* CONTROLLA SE SONO STATE UTILIZZATE TUTTE LE LETTERE DELLA CHIAVE
SE VEDE CHE SONO STATE USATE TUTTE , RESETTA IL TUTTO PARTENDO
DALLA PRIMA LETTERA */

crypt[i] = chiave[I] + frase[i] ; /* CRIPTA LA STRINGA */

if ((cfPtr = fopen( nomefile , "a")) == NULL)

printf("File gia aperto\n");



if ( crypt[i] < 100 ) fprintf(cfPtr, "0" ) ;; /* VERIFICA CHE IL VALORE DATO SIA MAGGIORE DI 100
E SE RISCONTRA UN VALORE MINORE DI 100 AGGIUNGE
IL VALORE 0 */
fprintf(cfPtr, "%d", crypt[i] ); /* STAMPA LA FRASE CRIPTATA */


I = 1 + I ; /* REALIZZA UNO SHIFT A DESTRA */

}

fprintf(cfPtr, "\n\n\nUsa decrypt per vedere il testo\n\n" ) ;
fprintf(cfPtr, "\n\n\nVersione programma 1.0\n\n" ) ;
fprintf(cfPtr, "\n\n\nwww.toki.it\n\n" ) ;
printf ("Il file testo è stato cryptato , per decryptarlo\n") ;

system("PAUSE"); /* COMANDO COMPATIBILE SOLO CON OS WIN , RICHIEDE LA
PRESSIONE DI UN TASTO PER CONTINUARE L'ESECUZIONE
DEL PROGRAMMA*/

}

int decrypt ()
{

int I=0 , i , countfrase , countchiave , dEcrypt[MAX] , de = 0 ;
char frase[MAX] , chiave[MAX] ;



printf ("Inserisci File Cryptato\n") ;
gets(frase) ;
printf ("Inserisci chiave\n") ;
gets(chiave) ;


countfrase = strlen(frase) ;
countchiave = strlen(chiave) ;

for ( i = 0 ; countfrase > i ; i = 3 + i)

{
if ( countchiave < I)
I = 0 ;;

dEcrypt[de] = (frase[i]* 100 + frase [i+1] * 10 + frase [i+2] +48 ) - chiave [I] ;

printf ("%c" , dEcrypt[I]) ;
I = 1 + I ;


}


printf ("\n") ;

system("PAUSE");

}

P8257 WebMaster
28-02-2003, 14.53.59
..Così è meglio..:


# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <conio.h>

/*
Name: CRYDEC TOKI
Author: KRAKZ
Date: 25/02/03 23.08
Description: CRYPTA E DECRYPTA
LICENZA : GNU|GPL
VERSIONE : 1.0
*/

void crypt (void) ;
void decrypt (void) ;

# define MAX 255

int main (void)
{
printf (" *** BENVENUTO SU CRYDEC VERSIONE 1.0 ***\n\n\n") ;
printf ("SELEZIONA UNA DELLE OPZIONI\n\n") ;
printf ("1 - Crypta\n") ;
printf ("2 - Decrypta\n") ;
printf ("3 - Info autori\n") ;
printf ("Digita 1, 2 o 3 ");
while (1)
{
switch(getch()) {
case 0+'1': crypt () ;
break ;

case 0+'2': decrypt () ;
break ;

case 0+'3': printf ("Krakz") ;
break ;

default: exit(0);
}
}
return 0;
}


void crypt (void)
{
int i, I = 0 , countchiave , countfrase , crypt[MAX] ;

char frase[MAX]="\0" , chiave[MAX]="\0" , nomefile[10]="\0" ;

FILE *cfPtr , *apri ;

printf ("Benvenuto su crypt 0.5\n") ;

printf ("Inserisci frase\n") ;
gets(frase) ;
printf ("Inserisci chiave\n") ;
gets(chiave) ;
printf ("Salva con nome\n") ;
gets(nomefile) ;


countfrase = strlen(frase) ; /* VERIFICA LA LUNGHEZZA DELLE STRINGHE */
countchiave = strlen(chiave) ;

for ( i = 0 ; countfrase > i ; i++) /* CONTROLLA CHE TUTTA LA STRINGA SIA CRIPTATA */


{

if ( countchiave < I) I = 0 ;; /* CONTROLLA SE SONO STATE UTILIZZATE TUTTE LE LETTERE DELLA CHIAVE
SE VEDE CHE SONO STATE USATE TUTTE , RESETTA IL TUTTO PARTENDO
DALLA PRIMA LETTERA */

crypt[i] = chiave[I] + frase[i] ; /* CRIPTA LA STRINGA */

if ((cfPtr = fopen( nomefile , "a")) == NULL)

printf("File gia aperto\n");



if ( crypt[i] < 100 ) fprintf(cfPtr, "0" ) ;; /* VERIFICA CHE IL VALORE DATO SIA MAGGIORE DI 100
E SE RISCONTRA UN VALORE MINORE DI 100 AGGIUNGE
IL VALORE 0 */
fprintf(cfPtr, "%d", crypt[i] ); /* STAMPA LA FRASE CRIPTATA */


I = 1 + I ; /* REALIZZA UNO SHIFT A DESTRA */

}

fprintf(cfPtr, "\n\n\nUsa decrypt per vedere il testo\n\n" ) ;
fprintf(cfPtr, "\n\n\nVersione programma 1.0\n\n" ) ;
fprintf(cfPtr, "\n\n\nwww.toki.it\n\n" ) ;
printf ("Il file testo è stato cryptato , per decryptarlo") ;

getch();

}

void decrypt (void)
{

int I=0 , i , countfrase , countchiave , dEcrypt[MAX] , de = 0 ;
char frase[MAX]="\0" , chiave[MAX]="\0" ;



printf ("Inserisci File Cryptato\n") ;
gets(frase) ;
printf ("Inserisci chiave\n") ;
gets(chiave) ;


countfrase = strlen(frase) ;
countchiave = strlen(chiave) ;

for ( i = 0 ; countfrase > i ; i = 3 + i)

{
if ( countchiave < I)
I = 0 ;;

dEcrypt[de] = (frase[i]* 100 + frase [i+1] * 10 + frase [i+2] +48 ) - chiave [I] ;

printf ("%c" , dEcrypt[I]) ;
I = 1 + I ;


}
getch();
}



Mi sono permesso di fare alcuni aggiustamenti ...
Le variabili in C devono essere inizializzate, altrimenti non saprai mai cosa contengono.

Bye :cool: