PDA

Visualizza la versione completa : [C] uso della funzione fflush


sizeof
19-09-2013, 11:07
Ciao a tutti..questo programma deve prendere in ingresso 10 elementi per il controllo del codice ISBN.
I primo 9 sono numeri mentre il decimo pu anche essere una "X" che equivale alla cifra "10".
Il decimo carattere un carattere di controllo.
Ho fatto questo programmino qualche anno fa ma ora compilandolo mi da un problema nella parte di inserimento degli elementi.
Ricordo di aver fatto in questo modo ma non ricordo pi la funzione fflush.
Potete aiutarmi?



#include <stdio.h>
#include <stdlib.h>
#define N 10

int main()
{
char isbn[ N ];
int s1[ N ];
int s2[ N ];
int i, verifica;
char car;

printf("Inserisci il codice ISBN di 10 cifre\n");

for ( i = 0; i < N; i++ ) {

scanf("%c", &car);
fflush(stdin);

if ( car == 'X' ) {
isbn[i] = 10;
}
else {
isbn[i] = car - '0';
}
}


printf("\n\n");

printf("Il codice ISBN : ");

for ( i = 0; i < 10; i++ ) {
printf("%d\t", isbn[i] );

}
s1[0] = isbn[0];
for ( i = 1; i < N; i++ ) {
s1[i] = s1[i - 1] + isbn[i];
}
printf("\n\n");

printf("Il vettore s1 :\n");

for ( i = 0; i < N; i++ ) {
printf("%d\t", s1[i] );

}

s2[0] = s1[0];
for (i = 1; i < N; i++) {
s2[i] = s2[ i - 1] + s1[i];
}

printf("\n\n");
printf("Il vettore s2 :\n");

for (i = 0; i < N; i++ ) {
printf("%d\t", s2[i] );
}

printf("\n\n");

verifica = s2[9] % 11;

if ( verifica == 0 ) {
printf("\nLa verifica andata a buon fine\n");
}
else {
printf("\nERRORE: La verifica NON andata a buon fine\n");
}


return 0;
}

Alex'87
19-09-2013, 11:11
Intendi questo (http://forum.html.it/forum/showthread.php?s=&postid=13913642#post13913642)?

sizeof
19-09-2013, 11:39
No non mio questo
Comunque ora sto provando in un altro modo, cio inserisco i primi 9 numeri nel vettore di int.
Poi vorrei utilizzare una varibiale di appoggio "car" sulla quale fare un controllo: se in ingresso metto un int allora isbn[9] = car se invece car = X in isbn[9] deve mettermi 10.
A questo punto non so che tipo di variabile utilizzare se di tipo int, char, unsigned char dato che deve poter immagazzinarmi o un intero oppure la X:



#include <stdio.h>
#include <stdlib.h>
#define N 10

int main()
{
int isbn[ N ];
int s1[ N ];
int s2[ N ];
int i, verifica;
unsigned char car;



for ( i = 0; i < N - 1; i++ ) {
printf("Inserisci l'elemnto %d : ", i + 1);
scanf("%d", &isbn[i]);
}

printf( "\nInserisci il carattere di controllo : \n");
scanf("%c", &car);

if ( car == 'X' ) {
isbn[9] = 10;
} else {
isbn[9] = car;
}




printf("\n\n");

printf("Il codice ISBN : \t");

for ( i = 0; i < 10; i++ ) {
printf("%d\t", isbn[i] );

}
s1[0] = isbn[0];
for ( i = 1; i < N; i++ ) {
s1[i] = s1[i - 1] + isbn[i];
}
printf("\n\n");

printf("Il vettore s1 :\n");

for ( i = 0; i < N; i++ ) {
printf("%d\t", s1[i] );

}

s2[0] = s1[0];
for (i = 1; i < N; i++) {
s2[i] = s2[ i - 1] + s1[i];
}

printf("\n\n");
printf("Il vettore s2 :\n");

for (i = 0; i < N; i++ ) {
printf("%d\t", s2[i] );
}

printf("\n\n");

verifica = s2[9] % 11;

if ( verifica == 0 ) {
printf("\nLa verifica andata a buon fine\n");
}
else {
printf("\nERRORE: La verifica NON andata a buon fine\n");
}


return 0;
}




non mi fa inserire il carattere di controllo!

sizeof
19-09-2013, 12:07
Ho fatto in questo modo:


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

int main()
{
int isbn[ 10 ];
int s1[ 10 ];
int s2[ 10 ];
int i, verifica;
char car;



for ( i = 0; i < 9; i++ ) {
printf("Inserisci l'elemnto %d : ", i + 1);
scanf("%d", &isbn[i]);
}

printf( "\nInserisci il carattere di controllo : \n");
scanf("%d", &car);

if ( car == 'X' ) {
isbn[9] = 10;
} else {
isbn[9] = car;
}




printf("\n\n");

printf("Il codice ISBN : \t");

for ( i = 0; i < 10; i++ ) {
printf("%d\t", isbn[i] );

}
s1[0] = isbn[0];
for ( i = 1; i < 10; i++ ) {
s1[i] = s1[i - 1] + isbn[i];
}
printf("\n\n");

printf("Il vettore s1 :\n");

for ( i = 0; i < 10; i++ ) {
printf("%d\t", s1[i] );

}

s2[0] = s1[0];
for (i = 1; i < 10; i++) {
s2[i] = s2[ i - 1] + s1[i];
}

printf("\n\n");
printf("Il vettore s2 :\n");

for (i = 0; i < 10; i++ ) {
printf("%d\t", s2[i] );
}

printf("\n\n");

verifica = s2[9] % 11;

if ( verifica == 0 ) {
printf("\nLa verifica andata a buon fine\n");
}
else {
printf("\nERRORE: La verifica NON andata a buon fine\n");
}


return 0;
}


Funziona ma se inserisco il carattere di controllo "X" mi va a mettere "0" e non "10" nell'ultima posizione del vettore. Qualcuno da dirmi perch? Grazie

sizeof
19-09-2013, 12:45
Allora ho risolto in questo modo, considerando l'inserimento del carattere X come NULL :


for ( i = 0; i < 9; i++ ) {
printf("Inserisci l'elemnto %d : ", i + 1);
scanf("%d", &isbn[i]);
}

printf( "\nInserisci il carattere di controllo : \n");
scanf("%d", &car);

if ( car == NULL ) {
isbn[9] = 10;
} else {
isbn[9] = car;
}


Anche se non mi pare una soluzione ideale in quanto qualsiasi carattere inserito che non sia un intero sar considerato NULL. Qualcuno di voi ha suggerimenti?

MItaly
19-09-2013, 15:26
Stai facendo molta confusione.

In primis, fflush(stdin) non portabile; alcuni compilatori (ad esempio VC++) ne consentono l'uso per svuotare il buffer di input, con altri (gcc) non fa niente; in generale, lo standard ne prevede l'uso solo per i file aperti in output, quindi evita fflush(stdin).


Funziona ma se inserisco il carattere di controllo "X" mi va a mettere "0" e non "10" nell'ultima posizione del vettore. Qualcuno da dirmi perch? Grazie
Perch
1) stai usando lo specificatore di formato "%d" quando quello che vuoi acquisire non un intero. Se inserisci X, la scanf vede un carattere che non un intero e quindi non lo acquisisci;
2) ancora peggio, stai usando "%d" ma passando un puntatore a char! Questo fa s che la scanf vada a sfasciare lo stack, corrompendo i dati delle variabili locali. Se vuoi acquisire caratteri devi usare %c e una variabile char, se vuoi acquisire numeri usi %d e una variabile int.

Allora ho risolto in questo modo, considerando l'inserimento del carattere X come NULL :
ancora sbagliato, per gli stessi motivi di cui sopra. E NULL si usa con i puntatori, non con i caratteri, per cui qui non c'entra niente.

Personalmente, io mi limiterei ad acquisire una stringa con tutto l'ISBN e poi farne il parsing separatamente.


char strISBN[100]={0};
int ISBN[10];
fgets(strISBN, sizeof(strISBN), stdin);
int i=0;
for(char *c=strISBN; *c && i<10; ++c, ++i)
{
if(c>='0' || c<='9') // converti i numeri
ISBN[i]=*c-'0';
else if(c=='x' || c=='X') // converti la X
ISBN[i]=10;
else if(c==' ' || c=='-' || c=='\n') // ignora i trattini e gli spazi
--i;
else
printf("Carattere non valido: %c", *c);
}

sizeof
19-09-2013, 16:02
Originariamente inviato da MItaly
Stai facendo molta confusione.

In primis, fflush(stdin) non portabile; alcuni compilatori (ad esempio VC++) ne consentono l'uso per svuotare il buffer di input, con altri (gcc) non fa niente; in generale, lo standard ne prevede l'uso solo per i file aperti in output, quindi evita fflush(stdin).


Perch
1) stai usando lo specificatore di formato "%d" quando quello che vuoi acquisire non un intero. Se inserisci X, la scanf vede un carattere che non un intero e quindi non lo acquisisci;
2) ancora peggio, stai usando "%d" ma passando un puntatore a char! Questo fa s che la scanf vada a sfasciare lo stack, corrompendo i dati delle variabili locali. Se vuoi acquisire caratteri devi usare %c e una variabile char, se vuoi acquisire numeri usi %d e una variabile int.

ancora sbagliato, per gli stessi motivi di cui sopra. E NULL si usa con i puntatori, non con i caratteri, per cui qui non c'entra niente.

Personalmente, io mi limiterei ad acquisire una stringa con tutto l'ISBN e poi farne il parsing separatamente.


char strISBN[100]={0};
int ISBN[10];
fgets(strISBN, sizeof(strISBN), stdin);
int i=0;
for(char *c=strISBN; *c && i<10; ++c, ++i)
{
if(c>='0' || c<='9') // converti i numeri
ISBN[i]=*c-'0';
else if(c=='x' || c=='X') // converti la X
ISBN[i]=10;
else if(c==' ' || c=='-' || c=='\n') // ignora i trattini e gli spazi
--i;
else
printf("Carattere non valido: %c", *c);
}


Ok allora con
char strISBN[100]={0}; inizializzo il buffer per lo stream di ingresso.
con
fgets(strISBN, sizeof(strISBN), stdin); leggo dallo stream di ingresso e metto l'ingresso nel buffer (inizializzato prima), giusto?

sizeof
19-09-2013, 16:40
Perch
for(char *c=strISBN; *c && i<10; ++c, ++i)
mi da errore...error: for loop initial declarations are only allowed in C99 mode| ??????

MItaly
19-09-2013, 17:04
Perch stai compilando in modalit C "classico" (C89); correggi spostando la creazione della variabile fuori dal ciclo.


char *c;
for(c=strISBN; *c && i<10; ++c, ++i)

sizeof
19-09-2013, 19:55
ok ho fatto cos:


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

int main()
{
char strISBN[100]={0};
int ISBN[10];
int s1[ 10 ];
int s2[ 10 ];
int verifica;
char car;
int i=0;


printf("Inserisci il codice ISBN : \n");

fgets(strISBN, sizeof(strISBN), stdin);
char *c;
for(c=strISBN; *c && i<10; ++c, ++i)
{
if(c>='0' || c<='9') // converti i numeri
ISBN[i]=*c-'0';
else if(c=='x' || c=='X') // converti la X
ISBN[i]=10;
else if(c==' ' || c=='-' || c=='\n') // ignora i trattini e gli spazi
--i;
else
printf("Carattere non valido: %c", *c);
}



printf("\n\n");

printf("Il codice ISBN : \t");

for ( i = 0; i < 10; i++ ) {
printf("%d\t", ISBN[i] );

}
s1[0] = ISBN[0];
for ( i = 1; i < 10; i++ ) {
s1[i] = s1[i - 1] + ISBN[i];
}
printf("\n\n");

printf("Il vettore s1 :\n");

for ( i = 0; i < 10; i++ ) {
printf("%d\t", s1[i] );

}

s2[0] = s1[0];
for (i = 1; i < 10; i++) {
s2[i] = s2[ i - 1] + s1[i];
}

printf("\n\n");
printf("Il vettore s2 :\n");

for (i = 0; i < 10; i++ ) {
printf("%d\t", s2[i] );
}

printf("\n\n");

verifica = s2[9] % 11;

if ( verifica == 0 ) {
printf("\nLa verifica andata a buon fine\n");
}
else {
printf("\nERRORE: La verifica NON andata a buon fine\n");
}


return 0;
}



ed ho notato che se inserisco la X non mi da 10 ed inoltre c' un altro problema: gli interi del codice possono avere anche 2 cifre e con lo stream in ingresso non le riconosce. Come posso fare?

Loading