[Powered by Google Translate] [File I / O]
[Jason Hirschhorn, Harvard University]
[Questo è CS50, CS50.TV]
Quando pensiamo a un file, quello che viene in mente è un documento di Microsoft Word,
un'immagine JPEG, o un brano MP3,
e interagire con ciascuno di questi tipi di file in modi diversi.
Ad esempio, in un documento Word aggiungiamo testo
mentre con un'immagine JPEG potremmo ritagliare i bordi o ritoccare i colori.
Eppure, sotto il cofano di tutti i file nel nostro computer non sono altro
di una lunga sequenza di zero e uno.
È alla specifica applicazione che interagisce con il file
per decidere come elaborare questa lunga sequenza e lo presenta per l'utente.
Da un lato, un documento può guardare solo un byte,
o 8 zero e uno, e visualizzare un carattere ASCII sullo schermo.
D'altra parte, una immagine bitmap può guardare 3 byte,
o 24 zero e uno,
e li interpretano come 3 numeri esadecimali
che rappresentano i valori di rosso, verde e blu
a un pixel di un'immagine.
Qualunque cosa può apparire come sullo schermo, nella loro essenza,
i file non sono altro che una sequenza di zero e uno.
Quindi cerchiamo di immersione e di vedere come in realtà abbiamo manipolare questi zero e uno
quando si tratta di scrittura e la lettura da un file.
>> Inizierò suddividendolo in un semplice processo in 3 parti.
Successivamente, verrà tuffarsi in due esempi di codice che illustrano queste tre parti.
Infine, esamineremo il processo e alcuni dei suoi più importanti.
Come con qualsiasi file che si trova sul desktop,
la prima cosa da fare è aprirlo.
In C facciamo dichiarando un puntatore ad una struct predefinito
che rappresenta un file su disco.
In questa chiamata di funzione, anche noi decidere se vogliamo scrivere o leggere dal file.
Quindi, facciamo la lettura effettiva e la scrittura.
Ci sono un certo numero di funzioni specializzate possiamo usare in questa parte,
e quasi tutti iniziano con la lettera F, che sta per file.
Infine, simile alle X rosse nell'angolo in alto dei file aperti sul computer,
chiudiamo il file con una chiamata di funzione finale.
Ora che abbiamo un'idea generale di ciò che andremo a fare,
tuffiamoci nel codice.
>> In questa directory, ci sono due file C e dei loro file eseguibili corrispondenti.
Il programma di macchina da scrivere accetta un argomento della riga di comando,
il nome del documento che si vuole creare.
In questo caso, che chiameremo doc.txt.
Corriamo il programma e inserire un paio di righe.
Ciao. Il mio nome è Jason.
Infine, bisogna digitare "quit".
Se ora elencare tutti i file in questa directory,
vediamo che esiste un nuovo documento chiamato doc.txt.
Questo è il file di questo programma appena creato.
E, naturalmente, è troppo altro che una lunga sequenza di zero e uno.
Se apriamo questo nuovo file,
vediamo le 3 righe di codice che abbiamo inserito nel nostro programma -
Ciao. Nome maggio è Jason.
Ma quello che sta realmente accadendo quando typewriter.c corre?
La prima linea di interesse per noi è la linea 24.
In questa linea, dichiariamo il nostro puntatore al file.
La funzione che restituisce il puntatore, fopen, accetta due argomenti.
Il primo è il nome del file inclusa l'estensione, se del caso.
Ricordiamo che un'estensione di file non influenza il file al suo livello più basso.
Siamo sempre a che fare con una lunga sequenza di zero e uno.
Ma lo fa influenza come i file vengono interpretati e quali applicazioni vengono utilizzate per aprirli.
Il secondo argomento di fopen è una singola lettera
che si distingue per quello che abbiamo in programma di fare dopo che aprire il file.
Ci sono tre opzioni per questo argomento - W, R, e A.
Abbiamo scelto w in questo caso perché vogliamo scrivere nel file.
R, come si può intuire, è per la lettura del file.
E una è per l'aggiunta al file.
Mentre sia w e può essere utilizzato per la scrittura di file,
w Inizieremo scrivendo dall'inizio del file
e potenzialmente sovrascrivere tutti i dati che sono stati precedentemente memorizzati.
Per impostazione predefinita, il file si apre, se non esiste già,
viene creato nella directory di lavoro corrente.
Tuttavia, se vogliamo accedere o creare un file in una posizione diversa,
nel primo argomento di fopen,
si può specificare un percorso di file, oltre al nome del file.
Mentre la prima parte di questo processo è solo una linea di codice lungo,
è sempre buona norma includere un altro insieme di linee
che controllare che il file è stato aperto o creato.
Se fopen restituisce il valore null, che non vorrebbe andare avanti con il nostro programma,
e questo può accadere se il sistema è operativo su memoria
o se si tenta di aprire un file in una directory per la quale non abbiamo avuto i giusti permessi.
>> La seconda parte del processo avviene in ciclo while macchina da scrivere.
Usiamo un CS50 funzione di libreria per ricevere l'input da parte dell'utente,
e assumendo che non si vuole uscire dal programma,
usiamo le fputs funzione per prendere la stringa e scrivere al file.
fputs è solo una delle tante funzioni che potremmo usare per scrivere nel file.
Altri includono fwrite, fputc, e anche fprintf.
Indipendentemente dalla particolare funzione si finisce per utilizzare, però,
tutti hanno bisogno di sapere, attraverso i loro argomenti,
almeno due cose -
ciò che deve essere scritto e dove deve essere scritto.
Nel nostro caso, l'ingresso è la stringa che deve essere scritto
e fp è un puntatore che ci indirizza al punto in cui stiamo scrivendo.
In questo programma, la seconda parte del processo è piuttosto semplice.
Stiamo semplicemente prendendo una stringa dall'utente
e l'aggiunta direttamente al nostro file con poco-a-no di convalida dell'input o controlli di sicurezza.
Spesso, tuttavia, la seconda parte si occupano la maggior parte del codice.
Infine, la terza parte è on line 58, in cui chiudiamo il file.
Qui chiamiamo fclose e passare il nostro puntatore del file originale.
Nella riga successiva, si ritorna a zero, che segna la fine del nostro programma.
E, sì, la terza parte è così semplice come sembra.
>> Passiamo alla lettura da file.
Nel nostro elenco abbiamo un file chiamato printer.c.
Facciamo correre con il file che abbiamo appena creato -
doc.txt.
Questo programma, come suggerisce il nome, semplicemente stampare il contenuto del file passato.
E non l'abbiamo.
Le righe di codice che avevamo scritto in precedenza e salvato in doc.txt.
Ciao. Il mio nome è Jason.
Se ci immergiamo in printer.c,
si vede che un sacco di codice è simile a quello che abbiamo appena attraversato in typewriter.c.
Infatti linea 22, dove abbiamo aperto il file,
e la linea 39, dove abbiamo chiuso il file,
sono entrambi quasi identica a typewriter.c, salvo argomento fopen secondo.
Questa volta stiamo leggendo da un file,
così abbiamo scelto r invece di w.
Così, concentriamoci sulla seconda parte del processo.
In linea 35, la seconda condizione nel nostro 4 loop,
facciamo una chiamata a fgets,
la funzione compagno di fputs da prima.
Questa volta abbiamo tre argomenti.
Il primo è il puntatore alla matrice di caratteri in cui la stringa verranno memorizzati.
Il secondo è il numero massimo di caratteri da leggere.
E il terzo è il puntatore al file con il quale stiamo lavorando.
Si noterà che il ciclo for termina quando fgets restituisce null.
Ci sono due motivi che ciò possa essere accaduto.
In primo luogo, un errore potrebbe essersi verificato.
Secondo, e più probabilmente, alla fine del file è stato raggiunto e più caratteri sono stati letti.
Nel caso vi stiate chiedendo, due funzioni esistono che ci permettono di dire
che la ragione è la causa di questo puntatore nullo particolare.
E, non a caso, dal momento che hanno a che fare con il lavoro con i file,
sia la funzione ferror e l'inizio funzione feof con la lettera f.
>> Infine, prima di concludere, una breve nota sulla fine della funzione di file,
che, come appena detto, è scritto come feof.
Spesso vi troverete con while e for cicli di leggere progressivamente il vostro senso attraverso i file.
Quindi, avrete bisogno di un modo per porre fine a queste loop dopo aver raggiunto la fine di questi file.
Chiamare feof sul vostro puntatore del file e controllare per vedere se è vero
avrebbe fatto proprio questo.
Così, un ciclo while con la condizione (! Feof (fp)) potrebbe sembrare una soluzione perfettamente adeguata.
Tuttavia, dire che abbiamo una linea a sinistra nel nostro file di testo.
Ci entrare nel nostro ciclo while e tutto funzionerà come previsto.
Nel round successivo attraverso, il nostro programma verificherà se feof di fp è vero,
ma - e questo è il punto cruciale da capire -
non sarà vero per il momento.
Questo perché l'obiettivo di feof non è quello di verificare
se la chiamata successiva a una funzione leggere colpirà la fine del file,
ma piuttosto di verificare se la fine del file è già stato raggiunto.
Nel caso di questo esempio,
leggere l'ultima riga del nostro file va perfettamente senza intoppi,
ma il programma non sa ancora che abbiamo colpito la fine del nostro file.
Solo quando lo fa una lettura supplementari che neutralizza la fine del file.
Pertanto, una condizione corretta sarebbe il seguente:
fgets e le sue tre argomenti - di uscita, dimensioni della produzione, e FP -
e tutto questo non uguale a null.
Questo è l'approccio che abbiamo adottato in printer.c,
e in questo caso, dopo il ciclo termina,
si potrebbe chiamare feof o ferror per informare l'utente circa la motivazione specifica per uscire questo ciclo.
>> La scrittura e la lettura da un file è, nella sua forma più semplice,
un semplice processo in 3 parti.
Per prima cosa, apriamo il file.
In secondo luogo, abbiamo messo alcune cose nel nostro file o prendere alcune cose fuori di esso.
In terzo luogo, chiudere il file.
La prima e l'ultima sono facili.
La parte centrale è dove si trova la roba difficile.
E anche se sotto il cofano ci stiamo sempre a che fare con una lunga sequenza di zero e uno,
non aiutano quando si scrive codice per aggiungere un livello di astrazione
che trasforma la sequenza in qualcosa che assomiglia più da vicino quello che siamo abituati a vedere.
Per esempio, se stiamo lavorando con un 24-bit file bitmap,
saremo probabilmente leggere o scrivere tre byte alla volta.
In tal caso, non avrebbe molto senso per definire e assegnare un nome appropriato
una struttura che si trova a 3 byte di grandi dimensioni.
>> Anche se si lavora con file può sembrare complicato,
utilizzarli ci permette di fare qualcosa di veramente notevole.
Siamo in grado di modificare lo stato del mondo esterno il nostro programma,
siamo in grado di creare qualcosa che vive al di là della vita del nostro programma,
o si può anche cambiare qualcosa che è stato creato prima del nostro programma è stato avviato in esecuzione.
Interagire con i file è una parte davvero potente della programmazione in C.
e io sono felice di vedere che cosa si sta andando a creare con essa nel codice a venire.
Il mio nome è Jason Hirschhorn. Questo è CS50.
[CS50.TV]
>> [Risate]
Va bene. Un prendere. Ci siamo.
Quando pensiamo a un file - >> Oh, aspetta. Scusi.
[Risate] Ok.
Hey there.
Quando pensiamo a un file -
Quando si pensa di un file - Ok. Dimmi quando sei pronto.
Oh, fantastico.
Anche se la lettura da un gobbo può sembrare - n. Il mio male.