SPEAKER: Hidtil, er det sandsynligt at de fleste af dine programmer har været lidt flygtig. Du kører et program som Mario eller grådige. Det gør noget, er det måske beder brugeren om nogle oplysninger, udskrive nogle output til skærmen, men så når dit program er slut, der er virkelig ingen beviser der Det blev aldrig køre i første omgang. Jeg mener, sikker, du måske har forladt det åbne i terminalvinduet, men hvis du rydde skærmen, er der virkelig ingen beviser for, at det eksisterede. Vi har ikke et middel til lagring vedvarende information, information der eksisterer efter vores Programmet er stoppet, eller vi ikke op til dette punkt. Heldigvis dog, c gør give os mulighed at gøre dette ved at gennemføre noget, der hedder en fil, en struktur, som stort set repræsenterer en fil, som du ville fordoble klik på din computer, hvis du er anvendes til en grafisk brugermiljø. Generelt når der arbejdes med C, men vi er faktisk kommer til at arbejde med henvisninger til files-- fil stars-- bortset fra en lille smule når vi taler om et par af de funktioner, arbejde med fil pointere. Du behøver ikke at have virkelig gravet for dybt ind i forståelse pointers selv. Der er en lille teeny smule hvor vi vil tale om dem, men generelt fil pointers og pointere, mens indbyrdes forbundne, er ikke nøjagtigt det samme. Nu hvad mener jeg, når Jeg siger vedholdende data? Hvad er vedvarende data? Hvorfor har vi bekymrer sig om det? Sige, for eksempel, at du kører et program eller du har omskrevet en program, der er et spil, og du ønsker at holde styr af alle brugerens bevægelser så måske hvis noget går galt, du kan gennemgå filen efter kampen. Det er, hvad vi mener, når vi tale om persistente data. I løbet af at køre din program, er en fil oprettet. Og når dit program er stoppet, at filen stadig findes på dit system. Og vi kan se på det og undersøge det. Og så programmet vil blive indstillet til har skabt nogle vedholdende data, Der findes data, efter at programmet er færdig med at køre. Nu er alle disse funktioner, der arbejder med at skabe filer og manipulere dem på forskellige måder bor i standard io.h, som er en header fil, du sandsynligvis har været pund herunder i toppen af ​​smukke meget alle dine programmer fordi den indeholder en af ​​de mest nyttige funktioner for os, printf, som også lader bor i standard io.h. Så du behøver ikke at pund omfatter yderligere filer formentlig med henblik på at arbejde med fil pointers. Nu hver enkelt fil pointer-funktion, eller hver enkelt fil I / O, input output funktion, accepterer som en af dens parametre eller input en fil pointer-- bortset for én, fopen, som er, hvad du bruger til at få filen pointer i første omgang. Men når du har åbnet fil, og du får fil pointere, du kan derefter passere dem som argumenter til de forskellige funktioner vi kommer til at tale om dag, samt mange andre så du kan arbejde med filer. Så der er seks temmelig fælles grundlæggende dem at vi kommer til at tale om i dag. fopen og dens følgesvend funktion fclose, fgetc og dens følgesvend funktion fputc, og fread og dens følgesvend funktion, fwrite. Så lad os få ret i det. fopen-- hvad gør det? Tja, det åbner en fil, og det giver dig en fil pegepind til det, så du derefter kan bruge det fil pointer som et argument ethvert af den anden fil I / O-funktioner. Det vigtigste at huske med fopen er, at efter du har åbnet fil eller foretaget et opkald som den her, du nødt til at tjekke for at sikre at markøren at du fik tilbage er ikke lig med nul. Hvis du ikke har set videoen på pointere, kan dette ikke mening. Men hvis du prøver og dereference en null pointer tilbagekaldelse, dit program vil formentlig lide en segmentering [uhørligt]. Vi ønsker at sikre, at vi fik en legitim pointer tilbage. Langt størstedelen af ​​den tid, vi vil har fået en legitim pointer tilbage og det vil ikke være et problem. Så hvordan kan vi foretage et opkald til fopen? Det ser temmelig meget som denne. Fil stjerne ptr-- PTR være en generisk navn til filen pointer-- fopen og vi passerer i to ting, et filnavn og en operation, vi ønsker at foretage. Så vi har måske et opkald, der ligner denne-- fil stjerne PTR 1 er lig med fopen file1.txt. Og operationen, jeg har valgt, er r. Så hvad tror du r er her? Hvad er den slags ting, vi kan være i stand til at gøre for at filer? Så r er operation, som vi vælge, når vi ønsker at læse en fil. Så vi ville dybest set, når Vi foretager et opkald som denne være at få os en fil pointer sådan, at vi så kunne læse oplysninger fra file1.txt. Tilsvarende kunne vi åbne filen 2.txt til at skrive og så vi kan passere ptr2, filen pointer jeg har oprettet her, som et argument for enhver funktion, skriver information til en fil. Og ligner skriftligt, er der også mulighed for at tilføje en. Forskellen mellem skrive og tilføje er, at når du skriver til en fil, hvis du foretage et opkald til fopen til skrivning og at filen findes allerede, er det kommer til at overskrive hele filen. Det kommer til at starte i begyndelsen, slette alle de oplysninger, Det er der allerede. Hvorimod hvis du åbner den for at tilføje, det vil gå til slutningen af ​​filen hvis der er allerede tekst i det eller oplysninger i det, og det vil derefter begynde skriver derfra. Så vil du ikke miste nogen af ​​de oplysninger, du har gjort før. Uanset om du ønsker at skrive eller tilføje slags afhænger af situationen. Men du vil sikkert vide, hvad rigtige betjening er, når den tid kommer. Så det er fopen. Hvad med fclose? Nå, temmelig enkelt, fclose bare accepterer filen pointer. Og som man kunne forvente, det lukker filen. Og når vi har lukket en fil, kan vi ikke udføre mere fil I / O-funktioner, læse eller skrive, på den pågældende fil. Vi er nødt til at genåbne indgive en anden gang med henblik på at arbejde videre med den ved hjælp af I / O-funktioner. Så fclose midler vi er færdige arbejde med denne fil. Og alle vi nødt til at passere i, er navnet på en fil pointer. Så på et par glider siden, vi fopened fil 1 dot tekst til læsning og vi tildelt, at fil pointer til ptr1. Nu har vi besluttet vi er færdig med at læse fra filen. Vi behøver ikke at gøre mere med det. Vi kan bare fclose ptr1. Og på samme måde, kunne vi fclose de andre. Okay. Så der er åbning og lukning. Det er de to grundlæggende igangsætning. Nu vil vi faktisk gøre nogle interessante ting, og den første funktion, som vi vil se, der vil gøre det er fgetc-- fil får et tegn. Det er, hvad fgetc generelt ville oversætte til. Dens mål i livet er at læse næste tegn, eller hvis dette er din helt første opkald til fgetc til en bestemt fil, det første tegn. Men så efter det, du får den næste, meget næste karakter af denne fil, og gemmer det i en variabel karakter. Som vi har gjort her, char ch lig fgetc, passere i navnet på en fil pointer. Igen, det er meget her vigtigt at huske at for at få denne operation lykkes, filen pointer selv mĺ have blevet åbnet for læsning. Vi kan ikke læse et tegn fra en fil pointer, som vi åbnede for skrivning. Så det er en af ​​de begrænsninger af fopen, ikke? Vi er nødt til at begrænse os selv til kun at udføre en operation med én fil pointer. Hvis vi ønskede at læse og skrive fra den samme fil, ville vi have åbent to separate fil henvisninger til samme file-- én for læsning, én for skrivning. Så igen, den eneste grund Jeg bringer det op nu, er for hvis vi kommer til at foretage et opkald til fgetc, at filen pointer må have blevet åbnet for læsning. Og så temmelig enkelt, alt, hvad vi behøver at gøre er passere i navnet på filen pointer. Så char ch lig fgetc ptr1. Det kommer til at få os næste character-- eller igen, hvis dette er den første gang vi har lavet denne indkaldelse, den første character-- uanset fil er peget på af ptr1. Husk på, at det var fil 1 dot tekst. Det får det første tegn i det og vi vil gemme det i variablen lm. Temmelig ligetil. Så vi har kun set på tre funktioner og allerede vi kan gøre noget temmelig pæn. Så hvis vi tager denne evne for at få en karakter og vi loop it-- så vi fortsætte med at få tegn fra en fil over og igen og over-- nu er vi kan læse hver eneste karakter af en fil. Og hvis vi udskriver hvert tegn umiddelbart efter, at vi læser det, Vi har nu læst fra en fil og trykt dens indhold til skærmen. Vi har effektivt sammenkædet filen på skærmen. Og det er, hvad det Linux kommando kat gør. Hvis du skriver kat i filnavnet, det vil udskrive hele indholdet af filen i dit terminalvindue. Og så denne lille løkke her, kun tre linjer kode, men det effektivt dubletter Linux-kommandoen kat. Så denne syntaks måske ser lidt underligt, men her er, hvad der sker her. Mens lm lig fgetc, ptr er ikke svarende til EOF-- det er en hel mundfuld, men lad os bryde det ned lige så det er klar på syntaksen. Jeg har konsolideret det af hensyn til plads, selv om det er lidt syntaktisk tricky. Så denne del i grøn højre nu, hvad det gør? Tja, det er bare vores fgetc opkald, ikke? Vi har set det før. Det er at få en karakter fra filen. Så vi sammenligner, at karakter mod EOF. EOF er en særlig værdi, der er defineret i standard io.h, som er slutningen af ​​filen karakter. Så dybest set, hvad der vil ske er denne løkke vil læse et tegn, sammenligne det med eof, den slutningen af ​​filen karakter. Hvis de ikke stemmer overens, så vi ikke har nået enden af ​​filen, vi vil printe denne karakter ud. Så vil vi gå tilbage til begyndelsen af ​​sløjfen igen. Vi får en karakter, skal du kontrollere mod EOF, printe den ud, og så videre og så videre og så videre, looping igennem på den måde indtil vi har nået slutningen af ​​filen. Og derefter ved dette punkt, Vi vil have udskrevet ud hele indholdet af filen. Så igen, har vi kun set fopen, fclose, og fgetc og allerede kan vi kopiere en Linux terminal kommando. Som jeg sagde i begyndelsen, vi havde fgetc og fputc, og fputc var følgesvend funktion fgetc. Og så, som du måske forestiller dig, Det er skriften tilsvarende. Det giver os mulighed for at skrive en enkelt tegn i en fil. Igen, det forbehold er, lige ligesom det var med fgetc, filen at vi skriver til skal har været åbnet for skriftligt eller til at tilføje. Hvis vi forsøge at benytte fputc på en fil at vi har åbnet for læsning, vi kommer til at lide lidt af en fejltagelse. Men opkaldet er ret enkel. fputc kapital En ptr2, alle der kommer til at gøre, er at det er vil skrive brevet i A i fil 2 prik tekst, som var navnet på den fil, at vi åbnede og tildeles markøren til ptr2. Så vi kommer til at skrive en kapital A til fil 2 dot tekst. Og vi vil skrive et udråbstegn pege på filen 3 prik tekst, der blev peget på af ptr3. Så igen, temmelig ligetil her. Men nu kan vi gøre en anden ting. Vi har dette eksempel vi var bare at gå over om at være i stand til at replikere katten Linux kommando, den ene, der udskriver på skærmen. Nå, nu hvor vi har mulighed for at læse tegn fra filer og skrive tegn til filer, hvorfor vi ikke bare erstatte, at ringe til printf med en opfordring til fputc. Og nu har vi duplikeret cp, en meget grundlæggende Linux kommando at vi talte om vejen lang siden i linux kommandoer video. Vi har effektivt duplikeres, at lige her. Vi læser en karakter og så er vi skrive denne karakter til en anden fil. Læsning fra en fil, skrivning til en anden, igen og igen og igen, indtil vi ramte EOF. Vi har fået til slutningen af ​​den fil vi forsøger at kopiere fra. Og ved at vi vil have skrevet alle af de tegn, vi har brug for til filen at vi skriver til. Så dette er cp, Linux kopi kommando. I begyndelsen af denne video, jeg havde det forbehold at vi ville tale et lidt om pointere. Her er specifikt, hvor vi er vil tale om pejlemærker Ud over at indgive pointere. Så denne funktion ser lidt skræmmende. Det har fået flere parametre. Der er en masse foregår her. Der er en masse forskellige farver og tekster. Men virkelig, det er bare den generisk version af fgetc der giver os mulighed for at få nogen mængde information. Det kan være en smule ineffektivt, hvis vi er få tegn en ad gangen, iteration gennem filen et tegn ad gangen. Ville det ikke være pænere at få 100 ad gangen eller 500 ad gangen? Nå, fread og dens følgesvend funktion fwrite, som vi taler om i en anden, giver os mulighed for at gøre netop dette. Vi kan læse en vilkårlig mængde af oplysninger fra en fil og vi gemmer det et sted midlertidigt. I stedet for at være i stand til blot passer det i en enkelt variabel, vi måske nødt til at gemme det i et array. Og så, vi passerer i fire argumenter for at fread-- en pegepind til det sted, hvor vi er kommer til at gemme oplysninger, hvor stor hver informationsenhed vil være, hvor mange enheder af information vi ønsker at erhverve, og fra hvilken fil, vi ønsker at få dem. Sandsynligvis bedst illustreret med et eksempel her. Så lad os sige, at vi erklærer et array af 10 heltal. Vi har netop erklæret på stable vilkårligt int arr 10. Så det er temmelig ligetil. Nu, hvad vi gør imidlertid den frecall er vi læser størrelse int gange 10 bytes af information. Størrelse af int væsen four-- det er størrelsen af ​​et heltal i c. Så det, vi gør, er at vi læser 40 bytes værd af oplysninger fra filen peget på af PTR. Og vi opbevare dem 40 bytes eller andet sted hvor vi har afsat 40 byte værd af hukommelse. Heldigvis har vi allerede gjort, at ved erklære arr, at vifte lige der. Der er i stand bedrift 10 fire-byte enheder. Så i alt kan det holde 40 byte værd af oplysninger. Og vi er nu læser 40 bytes af oplysninger fra filen, og vi opbevare det i arr. Recall fra videoen på pejlemærker, som navnet på et array, såsom arr, er egentlig bare en pointer til sin første element. Så når vi passere i arr der, vi er faktisk, passerer en pointer. Ligeledes kan vi gøre denne-- vi ikke nødvendigvis har brug for at redde vores buffer på stakken. Vi kunne også dynamisk allokere en buffer som dette, ved hjælp af malloc. Husk, når vi dynamisk allokere hukommelse, Vi gemmer det på bunke, ikke stakken. Men det er stadig en buffer. Det er stadig, i dette tilfælde, er holder 640 bytes information fordi en dobbelt fylder otte bytes. Og vi beder om 80 af dem. Vi ønsker at have plads til at holde 80 dobbeltværelser. Så 80 gange 8 er 640 bytes information. Og at opkald til fread er indsamle 640 bytes information fra filen pegede på ved PTR og lagring nu arr2. Nu kan vi også behandle fread ligesom en opfordring til fgetc. I dette tilfælde, vi prøver bare at få en karakter fra filen. Og vi har ikke brug for en matrix til at holde et tegn. Vi kan bare gemme det i et tegn variabel. Fangsten er dog, at når vi bare have en variabel, vi nødt til at passere i adressen på denne variabel fordi minde om, at første argument til fread er en pointer til det sted og hukommelse hvor vi ønsker at gemme oplysningerne. Igen, navnet på en array er en pointer. Så vi ikke behøver at gøre tegnet array. Men C, tegnet c Her er ikke et array. Det er bare en variabel. Og så er vi nødt til at bestå en tegnet c at angive at det er den adresse, hvor vi ønsker at gemme denne én byte af information, denne ene figur, vi indsamler fra PTR. Fwrite-- jeg vil gå igennem det lidt mere quickly-- er stort set den nøjagtige ækvivalent fread undtagen det er for at skrive i stedet for læsning, bare ligesom other-- vi har haft åben og tæt, får en karakter, skrive et tegn. Nu er det få vilkårlig mængden af ​​information, ret vilkårlig mængde information. Så ligesom før, vi kan har et array af 10 heltal hvor vi allerede har lagrede oplysninger, måske. Det var sandsynligvis nogle linjer kode der bør gå mellem disse to hvor jeg fylder arr med noget meningsfuldt. Jeg fylder den med 10 forskellige heltal. Og i stedet, hvad jeg er gør skriver fra arr og indsamling af oplysningerne fra arr. Og jeg tager, at oplysninger og lagde den ind i filen. Så i stedet for at det er fra filen til bufferen, vi nu går fra bufferen til filen. Så det er lige omvendt. Så igen, ligesom før, vi kan også have en bunke chunk hukommelse at vi har dynamisk tildelt og læses fra, at og skrive det til filen. Og vi har også en enkelt variabel stand til at holde en byte af information, såsom en karakter. Men igen, vi er nødt til at passere i adressen på denne variabel når vi ønsker at læse fra den. Så vi kan skrive de oplysninger, vi finder på denne adresse til filen pointer, PTR. Der er masser af andre stor fil I / O-funktioner at gøre forskellige ting udover dem vi har talt om i dag. Et par af dem du måske finde nyttige er fgets og fputs, der andrager af fgetc og fputc men for læsning en enkelt streng fra en fil. I stedet for et enkelt tegn, det vil læse en hel streng. fprintf, som dybest set giver dig at bruge printf til at skrive til filen. Så ligesom du kan gøre det variabel substitution hjælp den pladsholdere procent i og procent d, og så videre, med printf du kan ligeledes tage printf snor og udskrive noget ligesom til en fil. fseek-- hvis du har en dvd-afspiller er den analogi, jeg plejer at bruge her-- er lidt ligesom at bruge din spole tilbage og spole frem knapperne til at bevæge sig rundt i filmen. På samme måde kan du flytte rundt på filen. En af de ting inde at filstrukturen at C skaber for dig, er en indikator af, hvor du er i filen. Er du i det begynder ved byte nul? Er du på byte 100, byte 1.000, og så videre? Du kan bruge fseek til vilkårligt at flytte at indikator frem eller tilbage. Og ftell igen ligner en dvd-afspiller, er ligesom en lille ur, der fortæller dig, hvor mange minutter og sekunder du er i en bestemt film. Ligeledes ftell fortæller dig, hvordan mange bytes du er i filen. feof er en anden version detektere, om du har nået enden af ​​filen. Og ferror er en funktion som du kan bruge at afsløre, om noget har gået galt arbejdsmiljø med en fil. Igen, dette er bare ridse overfladen. Der er stadig masser mere fil I / O funktioner i standard io.h. Men det vil sandsynligvis få dig begyndte at arbejde med fil pointere. Jeg er Doug Lloyd. Det er CS50.