Comportamento insolito durante il passaggio di una matrice a una funzione

#include  #define SIZE 5 void func(int*); int main(void) { int i, arr[SIZE]; for(i=0; i<SIZE; i++) { printf("Enter the element arr[%d]: ", i); scanf("%d", &arr[i]); }//End of for loop func(arr); printf("The modified array is : "); for(i=0; i<SIZE; i++) printf("%d ", arr[i]); return 0; } void func(int a[]) { int i; for(i=0; i<SIZE; i++) a[i] = a[i]*a[i]; } 

Produzione :::

alt text

Mentre inserisco gli elementi interi, l’output è OK. Ma come ho inserito un valore float come 1.5, non ha richiesto altri elementi e l’O / P è come mostrato nella figura. Penso che dovrebbe essere implicitamente tipizzato da 1,5 a 1 ma non è successo..può dire perché è successo? Tutte le informazioni sul compilatore sono mostrate nella figura.

Quando scanf("%d") un valore come 1.5 la scansione si fermerà al punto decimale e restituirà 1.

La prossima volta che si chiama scanf , il puntatore punterà comunque al punto decimale e la scansione tornerà immediatamente perché non ci sono cifre da scansionare.

Dovresti controllare il valore di ritorno da scanf – ti dà il numero di elementi esaminati con successo che saranno 1 inizialmente per il 1 prima del punto decimale e 0 da allora in poi.

Per scanf , scanf sta per “scan formatted” e ti garantisco che non troverai nulla di più non formattato dell’input dell’utente.

Indagare esaminando i fgets per l’input di linea. Ecco una copia di una funzione che uso spesso per tali scopi:

 #include  #include  #define OK 0 #define NO_INPUT 1 #define TOO_LONG 2 static int getLine (char *prmpt, char *buff, size_t sz) { int ch, extra; // Get line with buffer overrun protection. if (prmpt != NULL) { printf ("%s", prmpt); fflush (stdout); } if (fgets (buff, sz, stdin) == NULL) return NO_INPUT; // If it was too long, there'll be no newline. In that case, we flush // to end of line so that excess doesn't affect the next call. if (buff[strlen(buff)-1] != '\n') { extra = 0; while (((ch = getchar()) != '\n') && (ch != EOF)) extra = 1; return (extra == 1) ? TOO_LONG : OK; } // Otherwise remove newline and give string back to caller. buff[strlen(buff)-1] = '\0'; return OK; } 

 // Test program for getLine(). int main (void) { int rc; char buff[10]; rc = getLine ("Enter string> ", buff, sizeof(buff)); if (rc == NO_INPUT) { // Extra NL since my system doesn't output that on EOF. printf ("\nNo input\n"); return 1; } if (rc == TOO_LONG) { printf ("Input too long [%s]\n", buff); return 1; } printf ("OK [%s]\n", buff); return 0; } 

Una volta sscanf una linea con quella funzione, è ansible sscanf a proprio sscanf , gestendo gli errori molto più facilmente.

Quello che sta succedendo è che scanf interrompe la lettura di un intero quando vede il '.' carattere e lo lascia nel buffer di input. Quindi le successive chiamate a scanf falliscono perché il carattere successivo è '.' e non qualcosa di analizzabile come un intero.

come lo aggiusti? Il primo passo è quello di dimenticare di aver mai sentito parlare di scanf e di usare sempre fgets per leggere intere righe di input, quindi elaborarle dopo averle lette in un buffer di stringa. È ansible utilizzare sscanf per questo scopo, ma una funzione robusta come strtol sarebbe molto meglio.

Problema con il buffer: penso che la parte rimanente (.5) rimanga sul buffer. usa flushall(); dopo il tuo scanf("%d..