|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
[C]Aiuto per un programma
Ciao a tutti, sono agli inzi del C... ho un esercizio da fare per casa ma non so dove partire... mi potreste dare una mano per favore e mi potreste spiegare il programma?
ecco: Realizzare una funzione che permetta di introdurre da tastiera un dato numerico (intero o reale a scelta), eseguendo il controllo che l'introduzione sia corretta (cioe' che non ci siano stati errori di battitura. La funzione deve restituire il valore EOF se e' stato battuto <CTRL>+'Z'. Realizzare un programma main di collaudo. Grazie a tutti... ![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2773
|
Quali funzioni per l'input avete visto a scuola?
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
Allora, è una situazione un po' strana perchè in questo corso hanno unito 2 corsi e noi abbiamo fatto meno cose rispetto all'altro corso... Ad esempio me le hanno spiegate per la prima volta solo ieri...
Non capisco cosa intendo per che funzioni abbiamo visto... ![]() |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2773
|
Io lo farei in modo molto semplice usando insieme scanf() e getchar(), avete visto queste funzioni?
http://www.cplusplus.com/reference/c.../cstdio/scanf/ http://www.cplusplus.com/reference/c...stdio/getchar/ Procederei così: Provi a leggere un intero (o un reale) con scanf, se la lettura non riesce (cioè se scanf torna 0) consumi l'intero input con getchar fermandoti quando incontri '\n' o EOF: nel primo caso riprovi a leggere con scanf, nel secondo caso torni EOF. Se la lettura con scanf riesce ritorni il valore letto. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
Allora, innanzitutto grazie!!
![]() Getchar non l'ho mai visto... Scanf si... DI quello che mi hai spiegato non riesco a capire cosa vuol dire che lo scanf torna a zero se la lettura non riesce? Non so cosa voglia dire consumare lintero imput con getchar... Non capisco a dir la verità nemmeno cosa chiede il problema... ![]() |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2773
|
Quote:
Quando digiti qualcosa e premi invio quello che hai digitato (invio compreso, che è il carattere '\n') viene messo in un buffer di input (un buffer è un contenitore) e quando vengono richiamate funzioni come la getchar e la scanf parte di esso viene "consumato" (in sostanza mano a mano che leggi il buffer si svuota). Il problema chiede di scrivere una funzione che si occupi solo della lettura di un int o di un reale ma non come se ne occupa la scanf, che ritorna il valore zero se la lettura non riesce, ma che ritorni sempre un valore letto. Questo significa che quando l'utente digita un valore che non sia quello che ti aspetti (ad esempio int) la funzione in questione non deve ritornare un valore (come fa la scanf) ma deve attendere che l'utente inserisca un valore accettabile e solo a quel punto ritornarlo. |
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
Grazie mille per gli aiuti che mi stai dando...
Quindi da come ho capito devo far si che l'utente introduca un valore che ad esempio sia intero... Se l'utente invece introduce al posto che un numero intero un carattere lo scanf non acquisisce il valore ma rimane ad aspettare che l'utente acquisice un valore giusto? Codice:
#include <stdio.h> #include <stdlib.h> int scanf(){ int dato; printf("Introdurre un valore intero: "); scanf("%d",&dato); return; } int main(){ while (flag=0){ scanf(); if (scanf>0) flag=1; return 0; } Ste funzioni mi stanno facendo impazzire, al primo corso non ce le hanno nemmeno accennate :S... Ora per ogni cosa, come portare un valore da una funzione ad un'altra è un problema!! ![]() |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2773
|
Quote:
Secondo le richieste del tuo professore readInt deve ritornare un intero letto da tastiera oppure EOF se viene premuto CTRL+Z. Il main deve richiamare la funzione in modo da non essere implicato nella soluzione di questo particolare problema. In pratica il main sarà ad esempio: Codice:
int main(){ int val=readInt(); if(val!=EOF) printf("Hai inserito: %d\n",val); else printf("Hai premuto CTRL+Z\n"); } Poi c'è un problema: scanf se restituisce 0 non consuma dati nel buffer, quindi continuare a richiamare scanf non risolve il problema se viene inserito un "non intero" (vai in loop infinito). Era per risolvere questo problema che consigliavo di usare getchar: puoi leggere carattere per carattere finché non giungi alla fine del buffer (quindi '\n') e poi riprovare la lettura con scanf (o restituire EOF se invece di '\n' hai trovato EOF). PS: un'altra cosa, hai incluso stdlib.h ma per risolvere questo problema non serve Ultima modifica di wingman87 : 23-02-2010 alle 23:08. |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
Ah quindi il programma deve restituire che l'utente ha inserito Ctrl+Z se l'utente preme Ctrl+Z mandando lo scanf come valore a -1 e facendo scattare il EOF... Altrimenti se l'utente inserisce un numero intero giusto il programma restituisce solamente il numero inserito? QUindi bisogna trattare la funzione readint come un intero che deve essere analizzato dall 'if all'interno del main...
Grazie mille dell'aiuto... SOlo non ho ancora capito il fatto del getchar... P.S. Il professore ci fa usare come programma code blocks e il programma inserisce in automatico appena inzi sia stdio sia stdlib quindi lo metto sempre ma in realtà non so esattamente a cosa serve... ![]() Cmq così dici che va bene: Codice:
#include <stdio.h> int dato; int readint (valore) { printf("Inserisci un numero intero: "); scanf("%d", &valore); return (scanf); } int main(){ dato=readint (); if(dato!=EOF) printf("Il valore inserito e': %d", dato); else printf("Hai inserito Ctrl+Z"); return 0; } |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2773
|
In effetti non avevo notato che quando raggiungi EOF scanf ritorna proprio EOF.
Ho provato a scrivere la mia soluzione in codice ma ho trovato dei problemi. EOF in windows ha il valore -1, quindi sia che tu digitassi CTRL+Z sia che digitassi -1 con il sistema che descrivevo otterresti di aver raggiunto EOF, erroneamente nel secondo caso. Avrei dovuto pensarci prima in effetti. Allora, direi di dimenticare il getchar, anche perché è perfettamente sostituibile con Codice:
char carattere; scanf("%c",&carattere); http://digilander.libero.it/uzappi/C/C-funzioni.html Mi sembra fatto abbastanza bene. Dobbiamo ideare una nuova intestazione per la funzione che devi scrivere, in modo da poter distinguere il valore EOF dal valore -1. Potremmo usare: int readInt(int* var); E decidere che readInt restituisca 1 se ha letto un valore intero e *val conterrà il valore letto, e restituisca -1 se ha letto EOF (e val resterà invariato). La funzione verrà utilizzata in questo modo: Codice:
int main() { int dato; if (readInt(&dato)!=-1) printf("Il valore inserito e': %d", dato); else printf("Hai inserito Ctrl+Z\n"); return 0; } |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
Si penso di avercela fatta!!!
![]() ![]() Codice:
#include <stdio.h> #include <stdlib.h> int readint (int *val); int main() { int dato; if(readint(&dato)!=-1) printf("\nIl valore inserito e' %d\n",dato); else printf("Hai premuto Ctrl+Z\n"); return 0; } int readint (int *val){ int ret,flag=0,carattere=0; char car; printf("Introduci un numero intero: "); while (flag==0){ ret=0; ret=scanf("%d",val); if(ret<=0){ if (ret==EOF) flag=1; else{ ret=scanf("%c",&car); } } else printf("Letto intero: %d\n", *val); } return ret; } |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Feb 2010
Messaggi: 466
|
Quote:
|
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
Quindi se ho capito bene *val è solo l'indirizzo di dato... Quindi quando uso lo scanf devo dargli lo spazio all'interno del dato e quindi non metto * perchè così si prende lo spazio all'interno di dato visto che ho già detto alla funzione readint che val deve fare riferimento a dato?
|
![]() |
![]() |
![]() |
#14 | |
Senior Member
Iscritto dal: Feb 2010
Messaggi: 466
|
Quote:
![]() ![]() ![]() |
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
|
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: May 2001
Messaggi: 12814
|
Quote:
Supponendo che val sia una variabile normale: &val: è l'indirizzo di memoria di val Supponendo che val sia un puntatore (ovvero un indirizzo di memoria): *val: è l'operazione inversa di &, mi restituisce l'oggetto puntato da val. Quindi per farti un esempio, se val è una variabile semplice: *(&val) = val |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Feb 2010
Messaggi: 466
|
Quote:
int val = 100; quando tu fai riferimento a val , fai riferimento al contenuto di val quindi a 100 printf("%d",val) ; // ti stampa 100 invece &val è indirizzo di memoria di val , all'interno del quale è poi contenuto il valore della variabile. printf("0x%X",&val) ; // ti stampa qualcosa come 0xAABBCC ( che è l'indirizzo della memoria) scanf come parametri vuole degli indirizzi di memoria dentro i quali poi salverà i dati , è per questo che in genere si usa cosi: Codice PHP:
scanf come detto vuole un indirizzo, quindi nella tua funzione lo devi usare cosi : Codice PHP:
Codice PHP:
|
|
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Nov 2006
Città: Torino
Messaggi: 677
|
va bene... Grazie mille per l'aiuto a tutti!
![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:55.