RUNĀ: Līdz šim, visticamāk, lielākā daļa jūsu programmu ir bijušas
nedaudz īslaicīgas.
Jūs palaižat tādu programmu kā Mario vai Greedy.
Tā kaut ko dara, iespējams, liek lietotājam ievadīt kādu informāciju,
izdrukā kādu izvadi uz ekrāna, bet pēc tam, kad jūsu programma ir
beigusies, patiesībā nav nekādu pierādījumu, ka tā jebkad ir bijusi
palaista.
Es domāju, protams, jūs, iespējams, atstājāt to atvērtu termināļa
logā, taču, ja notīrīsit ekrānu, nekas neliecina, ka tā pastāvēja.
Mums nav līdzekļu, lai saglabātu pastāvīgu informāciju, informāciju,
kas saglabājas pēc mūsu programmas darbības pārtraukšanas, vai arī
mēs vēl neesam tikuši līdz šim brīdim.
Par laimi, c tomēr nodrošina mums iespēju to izdarīt, ieviešot kaut
ko, ko sauc par failu, struktūru, kas būtībā attēlo failu, uz kura
jūs datorā veiktu dubultklikšķi, ja esat pieradis pie grafiskas
lietotāja vides.
Parasti, strādājot ar c, mēs faktiski strādāsim ar norādēm uz
failiem — failu zvaigznītēm — izņemot mazliet, kad mēs runājam par
dažām funkcijām, kas darbojas ar failu rādītājiem.
Jums nav nepieciešams pārāk dziļi izprast pašās norādes.
Mēs par tām nedaudz parunāsim, taču parasti faila norādes un norādes,
lai arī ir savstarpēji saistītas, nav gluži viena un tā pati lieta.
Ko es domāju, kad es saku pastāvīgi dati?
Kas ir pastāvīgi dati?
Kāpēc mums tas rūp?
Piemēram, sakiet, ka izmantojat programmu vai esat pārrakstījis
programmu, kas ir spēle, un vēlaties sekot līdzi visām lietotāja
darbībām, lai, ja kaut kas noiet greizi, varētu pārskatīt failu pēc
spēles.
Tas ir tas, ko mēs domājam, runājot par pastāvīgiem datiem.
Programmas darbības laikā tiek izveidots fails.
Un, kad jūsu programma ir pārtraukusi darboties, šis fails joprojām
pastāv jūsu sistēmā.
Un mēs varam to apskatīt un pārbaudīt.
Un tā, lai programma būtu izveidojusi dažus pastāvīgus datus, dati
pastāv pēc programmas darbības pabeigšanas.
Tagad visas šīs funkcijas, kas darbojas ar failu izveidi un dažādu
veidu manipulācijām ar tiem, ir pieejamas standarta io.h failā, kas
ir galvenes fails, kas, iespējams, ir atrodams, tostarp gandrīz visu
savu programmu augšdaļā, jo tajā ir viena no mums noderīgākajām
funkcijām, printf, kas ļauj dzīvot arī standarta io.h.
Tāpēc, iespējams, lai strādātu ar failu norādēm, jums nav jāiekļauj
papildu faili.
Tagad katra atsevišķa faila rādītāja funkcija vai katra atsevišķa
faila I/O, ievades izvades funkcija, pieņem kā vienu no saviem
parametriem vai ievada faila rādītāju — izņemot vienu, fopen, kas ir
tas, ko jūs izmantojat, lai faila rādītāju ievietotu pirmā vieta.
Bet pēc tam, kad esat atvēris failu un saņemat faila norādes, varat
tos nodot kā argumentus dažādām funkcijām, par kurām mēs šodien
runāsim, kā arī daudzām citām, lai varētu strādāt ar failiem.
Tātad ir seši diezgan izplatīti pamata veidi, par kuriem mēs šodien
runāsim.
fopen un tā pavadošā funkcija fclose, fgetc un tā pavadošā funkcija
fputc, un fread un tās pavadošā funkcija fwrite.
Tāpēc skatīsim tieši to.
fopen — ko tas dara?
Tā atver failu un dod jums uz to faila rādītāju, lai jūs varētu
izmantot šo faila rādītāju kā argumentu jebkurai citai faila I/O
funkcijai.
Vissvarīgākais, kas jāatceras, izmantojot fopen, ir tas, ka pēc faila
atvēršanas vai zvanīšanas, piemēram, šeit, jums ir jāpārbauda, vai
rādītājs, kuru atgriezāt, nav vienāds ar nulli.
Ja neesat skatījies video par norādēm, tam var nebūt jēgas.
segmentācija [dzirdams].
Mēs vēlamies pārliecināties, ka esam atgriezuši īsto norādi .
Lielāko daļu laika mēs būsim dabūjuši atpakaļ īsto norādi , un tā
nebūs problēma.
Tātad, kā mēs varam izsaukt fopen?
Tas izskatās diezgan līdzīgi šim.
Faila zvaigznīte ptr — ptr ir vispārīgs faila norādesnosaukums —
fopen, un mēs nododam divas lietas: faila nosaukumu un darbību, ko
vēlamies veikt.
Tāpēc mums varētu būt izsaukums, kas izskatās šādi — faila zvaigznīte
ptr 1 ir vienāds ar fopen file1.txt.
Un operācija, ko esmu izvēlējusies, ir r.
Tātad, kas, jūsuprāt, šeit ir r?
Kādas darbības mēs varētu darīt ar failiem?
Tātad r ir darbība, kuru mēs izvēlamies, kad vēlamies lasīt failu.
Tātad, veicot šādu zvanu, mēs principā iegūtu faila norādi, lai mēs
varētu nolasīt informāciju no faila file1.txt.
Līdzīgi mēs varētu atvērt failu 2.txt rakstīšanai, lai mēs varētu
nodot ptr2, faila norādi, kuru esmu izveidojis šeit, kā argumentu
jebkurai funkcijai, kas ieraksta informāciju failā.
Līdzīgi kā rakstīšanai, ir arī iespēja pievienot, a.
Atšķirība starp rakstīšanu un pievienošanu ir tāda, ka, rakstot
failā, izsaucat fopen rakstīšanai un šis fails jau pastāv, tas
pārrakstīs visu failu.
Tas sāksies pašā sākumā, dzēšot visu jau esošo informāciju.
Savukārt, ja to atverat pievienošanai, tas nonāks faila beigās, ja
tajā jau ir teksts vai informācija, un pēc tam tas sāks rakstīt no
turienes.
Tātad jūs nezaudēsit nekādu informāciju, ko esat ievadījis iepriekš.
Tas, vai vēlaties rakstīt vai pievienot, ir atkarīgs no situācijas.
Bet jūs droši vien uzzināsiet, kāda ir pareizā darbība, kad pienāks
laiks.
Tātad tas ir fopen.
Kā ar fclose?
Nu, gluži vienkārši, fclose vienkārši pieņem faila norādi.
Un, kā jūs varētu gaidīt, tas aizver šo failu.
Pēc faila aizvēršanas mēs vairs nevaram veikt nekādas faila
ievades/izvades funkcijas — lasīšanas vai rakstīšanas šajā failā.
Mums ir atkārtoti jāatver fails citreiz, lai turpinātu strādāt ar to,
izmantojot I/O funkcijas.
Tātad fclose nozīmē, ka esam pabeiguši darbu ar šo failu.
Un viss, kas mums jāievada, ir faila norādesnosaukums.
Tāpēc pirms dažiem slaidiem mēs atvērām faila 1 punkta tekstu
lasīšanai un piešķīrām šī faila norādiptr1.
Tagad esam nolēmuši, ka esam pabeiguši šī faila lasīšanu.
Mums ar to nekas vairāk nav jādara.
Mēs varam vienkārši fclose ptr1.
Un līdzīgi, vai mēs varētu aizvērt pārējās.
Labi.
Tātad tā ir atvēršana un aizvēršana.
Tās ir divas pamata sākuma darbības.
Tagad mēs vēlamies paveikt dažas interesantas lietas, un pirmā
funkcija, ko mēs redzēsim, kas to darīs, ir fgetc — fails iegūst
rakstzīmi.
Tas ir tas, ko fgetc parasti nozīmētu.
Tā mērķis dzīvē ir nolasīt nākamo rakstzīmi vai, ja šis ir jūsu
pirmais fgetc izsaukums konkrētam failam, pirmo rakstzīmi.
Bet pēc tam jūs saņemat nākamo, šī faila nākamo rakstzīmi, un
saglabājat to rakstzīmju mainīgajā.
Kā mēs šeit esam darījuši, char ch ir vienāds ar fgetc, ievadiet
faila rādītāja nosaukumu.
Šeit atkal ir ļoti svarīgi atcerēties, ka, lai šī darbība būtu
veiksmīga, pašai faila norādeiir jābūt atvērtai lasīšanai.
Mēs nevaram nolasīt rakstzīmi no faila norādes, kuru atvērām
rakstīšanai.
Tātad tas ir viens no fopen ierobežojumiem, vai ne?
Mums ir jāierobežo tikai vienas darbības veikšana ar vienu faila
norādi.
Ja mēs vēlamies lasīt un rakstīt no viena faila, mums būtu jāatver
divas atsevišķas faila norādes uz vienu un to pašu failu — viena
lasīšanai, viena rakstīšanai.
Atkal, vienīgais iemesls, kāpēc es to pieminu, ir tāpēc, ka, ja mēs
izsauksim fgetc, faila norādeiir jābūt atvērtam lasīšanai.
Un tad diezgan vienkārši, viss, kas mums jādara, ir jānodod faila
norādesnosaukums.
Tātad char ch ir vienāds ar fgetc ptr1.
Tādējādi mēs iegūsim nākamo rakstzīmi — vai vēlreiz, ja šī ir pirmā
reize, kad mēs to izsaucām, pirmo rakstzīmi — jebkuram failam, uz
kuru norāda ptr1.
Atcerieties, ka tas bija faila 1 punkta teksts.
Tas iegūs pirmo rakstzīmi, un mēs to saglabāsim mainīgajā ch.
Diezgan vienkārši.
Tāpēc mēs esam apskatījuši tikai trīs funkcijas un jau varam paveikt
kaut ko diezgan glītu.
Tātad, ja mēs izmantojam šo spēju iegūt rakstzīmi un mēs veidojam
cilpu — tā mēs turpinām iegūt rakstzīmes no faila atkal un atkal un
atkal, tagad mēs varam nolasīt katru faila rakstzīmi.
Un, ja mēs izdrukājam katru rakstzīmi tūlīt pēc to izlasīšanas, mēs
tagad esam nolasījuši no faila un izdrukājuši tā saturu uz ekrāna.
Mēs esam efektīvi savienojuši šo failu ekrānā.
Un to dara Linux komanda cat.
Ja faila nosaukumā ierakstāt cat, tas izdrukās visu faila saturu jūsu
termināļa logā.
Un tā šī mazā cilpa šeit, tikai trīs koda rindiņas, bet tā efektīvi
dublē Linux komandu cat.
Tāpēc šī sintakse varētu šķist nedaudz dīvaina, taču lūk, kas šeit
notiek.
Kamēr ch ir vienāds ar fgetc, ptr nav vienāds ar EOF — tas ir ļoti
svarīgi , bet sadalīsim to, lai tas būtu skaidrs sintaksē.
Esmu to konsolidējis vietas dēļ, lai gan tas ir nedaudz sintaktiski
sarežģīts.
Tātad šī daļa šobrīd ir zaļā krāsā, ko tā dara?
Nu, tas ir tikai mūsu fgetc izsaukums, vai ne?
Mēs to esam redzējuši iepriekš.
Tas ir vienas rakstzīmes iegūšana no faila.
Tad mēs salīdzinām šo rakstzīmi ar EOF.
EOF ir īpaša vērtība, kas ir definēta standartā io.h, kas ir faila
rakstzīmes beigas.
Tātad būtībā tas, kas notiks, ir tas, ka šī cilpa nolasīs rakstzīmi,
salīdzinās to ar EOF, faila beigu rakstzīmi.
Ja tās nesakrīt, mēs neesam sasnieguši faila beigas, mēs izdrukāsim
šo rakstzīmi.
Pēc tam mēs atkal atgriezīsimies cilpas sākumā.
Mēs iegūsim rakstzīmi, pārbaudīsim, vai tas ir EOF, izdrukāsim to un
tā tālāk, un tā tālāk, un tā tālāk, tādā veidā cauri visai cilpai
līdz būsim sasnieguši faila beigas.
Un tad līdz tam brīdim mēs būsim izdrukājuši visu faila saturu.
Tātad atkal mēs esam redzējuši tikai fopen, fclose un fgetc, un mēs
jau varam dublēt Linux termināļa komandu.
Kā jau teicu sākumā, mums bija fgetc un fputc, un fputc bija fgetc
pavadošā funkcija.
Un tā, kā jūs varētu iedomāties, tas ir rakstīšanas ekvivalents.
Tas ļauj failā ierakstīt vienu rakstzīmi.
Atkal, brīdinājums, tāpat kā tas bija ar fgetc, failam, uz kuru mēs
rakstām, ir jābūt atvērtam rakstīšanai vai pievienošanai.
Ja mēģināsim izmantot fputc failā, kuru esam atvēruši lasīšanai, mēs
piedzīvosim nelielu kļūdu.
Bet zvans ir diezgan vienkāršs.
fputc capital A ptr2, viss, kas tiks darīts, ir ierakstīt burtu A
faila 2 punktu tekstā, kas bija faila nosaukums, kuru mēs atvērām un
piešķīrām norādiptr2.
Tātad mēs rakstīsim lielo A, lai failā būtu 2 punktu teksts.
Un mēs ierakstīsim izsaukuma zīmi failā ar 3 punktu tekstu, uz kuru
norādīja ptr3.
Tātad šeit atkal ir diezgan vienkārši.
Bet tagad mēs varam darīt citu lietu.
Mums ir šis piemērs, par kuru mēs tikko runājām par to, kā varētu
replicēt cat Linux komandu, kas tiek izdrukāta uz ekrāna.
Tagad, kad mums ir iespēja nolasīt rakstzīmes no failiem un rakstīt
rakstzīmes failos, kāpēc gan mēs vienkārši neaizstājam šo izsaukumu
uz printf ar izsaukumu uz fputc.
Un tagad mēs esam dublējuši cp — ļoti vienkāršu Linux komandu, par
kuru mēs jau sen runājām Linux komandu video.
Mēs to esam faktiski dublējuši tieši šeit.
Mēs lasām rakstzīmi un pēc tam rakstām to citā failā.
Lasīšana no viena faila, rakstīšana citā, atkal un atkal un atkal,
līdz mēs sasniedzam EOF.
Mēs esam nonākuši līdz faila beigām, no kura mēģinām kopēt.
Līdz ar to mēs esam ierakstījuši visas nepieciešamās rakstzīmes
failā, uz kuru mēs rakstām.
Tātad šī ir cp, Linux kopēšanas komanda.
Pašā šī video sākumā man bija brīdinājums, ka mēs nedaudz parunāsim
par norādēm.
Šeit mēs runāsim par norādēm papildus failu norādēm.
Tāpēc šī funkcija izskatās biedējoša.
Tai ir vairāki parametri.
Šeit daudz kas notiek.
Ir daudz dažādu krāsu un tekstu.
Bet patiesībā tā ir tikai vispārīgā fgetc versija, kas ļauj mums
iegūt jebkādu informācijas daudzumu.
Tas var būt nedaudz neefektīvi, ja mēs iegūstam rakstzīmes pa vienai,
atkārtojot failu pa vienai rakstzīmei.
Vai nebūtu patīkamāk saņemt 100 vienā reizē vai 500 vienā reizē?
Nu, fread un tā pavadošā funkcija fwrite, par kuru mēs runāsim pēc
sekundes, ļauj mums to izdarīt.
Mēs varam nolasīt noteikto informācijas daudzumu no faila, un
īslaicīgi to glabājam.
Tā vietā, lai to vienkārši ievietotu vienā mainīgajā, mums,
iespējams, tas ir jāsaglabā masīvā.
Tātad, mēs nododam fread četrus argumentus — norādi uz vietu, kur mēs
glabāsim informāciju, cik liela būs katra informācijas vienība, cik
informācijas vienību mēs vēlamies iegūt un no kura faila mēs vēlamies
tos iegūt.
Iespējams, vislabāk ilustrēt ar piemēru šeit.
Tātad pieņemsim, ka mēs deklarējam 10 veselu skaitļu masīvu.
Mēs tikko esam paziņojuši par lielu daudzumu noteiktu int arr 10.
Tātad tas ir diezgan vienkārši.
Tagad tas, ko mēs darām, ir tāds, ka mēs lasām informācijas lielumu,
kas ir int reiz 10 baiti.
Int lielums ir četri — tas ir vesela skaitļa lielums c.
Tātad mēs nolasām 40 baitus vērtu informāciju no faila, uz kuru
norādīja ptr.
Un mēs glabājam tos 40 baitus kaut kur, kur esam rezervējuši
40 baitus atmiņas.
Par laimi, mēs to jau esam izdarījuši, deklarējot arr, šo masīvu
tieši tur.
Tas spēj turēt 10 četru baitu vienības.
Tātad kopumā tajā var būt 40 baitu vērta informācija.
Tagad mēs nolasām 40 baitus informācijas no faila un saglabājam to
arr.
Atgādiniet no video par norādēm, ka masīva nosaukums, piemēram, arr,
patiesībā ir tikai norādeuz tā pirmo elementu.
Tātad, kad mēs ejam garām arr tur, mēs faktiski ejam garām norādei.
Līdzīgi mēs varam darīt to — mums nav obligāti jāsaglabā savs buferis
kaudzē.
Mēs varētu arī dinamiski piešķirt šādu buferi, izmantojot malloc.
Atcerieties, ka, dinamiski piešķirot atmiņu, mēs to saglabājam
kaudzītē, nevis kaudzē.
Bet tas joprojām ir buferis.
Šajā gadījumā tas joprojām glabā 640 baitus informācijas, jo
dubultnieks aizņem astoņus baitus.
Un mēs prasām 80 no tiem.
Mēs vēlamies, lai būtu vieta 80 dubulskaitļiem.
Tātad 80 reiz 8 ir 640 baitu informācija.
Un šis izsaukums Fread savāc 640 baitus informācijas no faila, uz
kuru norādīja ptr, un tagad to saglabā arr2.
Tagad mēs varam arī izturēties pret Fread tāpat kā ar izsaukumu
fgetc.
Šajā gadījumā mēs tikai cenšamies iegūt vienu rakstzīmi no faila.
Un mums nav nepieciešams masīvs, lai turētu rakstzīmi.
Mēs to varam vienkārši saglabāt rakstzīmju mainīgajā.
Tomēr jēga ir tāda, ka, ja mums ir tikai mainīgais, mums ir jānodod
šī mainīgā adrese, jo atcerieties, ka pirmais arguments, lai
izjauktu, ir norāde uz vietu un atmiņu, kur mēs vēlamies saglabāt
informāciju.
Atkal, masīva nosaukums ir norāde.
Tāpēc mums nav jāizvei do & array .
Bet c, rakstzīme c šeit, nav masīvs.
Tas ir tikai mainīgais.
Un tāpēc mums ir jānodod burts & c, lai norādītu, ka šī ir adrese,
kurā mēs vēlamies saglabāt šo vienu informācijas baitu, šo vienu
rakstzīmi, ko mēs apkopojam no ptr.
Fwrite — es to izskatīšu nedaudz ātrāk — ir gandrīz precīzs fread
ekvivalents, izņemot to, ka tas ir paredzēts rakstīšanai, nevis
lasīšanai, tāpat kā cits — mums ir bijis atvērts un aizvērts,
iegūstiet rakstzīmi, rakstiet rakstzīmi.
Tagad ir jāiegūst noteiktu informācijas daudzumu, pareizu noteiktas
informācijas daudzumu.
Tātad, tāpat kā iepriekš, mums var būt 10 veselu skaitļu masīvs,
kurā, iespējams, jau ir saglabāta informācija.
Iespējams, ka starp šīm divām koda rindām vajadzētu būt dažām koda
rindām, kurās es piepildu arr ar kaut ko nozīmīgu.
Es to aizpildu ar 10 dažādiem veseliem skaitļiem.
Un tā vietā es rakstu no arr un apkopoju informāciju no arr.
Un es ņemu šo informāciju un ievietoju failā.
Tā vietā, lai tas būtu no faila uz buferi, mēs tagad pārejam no
bufera uz failu.
Tātad ir tikai otrādi.
Tātad, tāpat kā iepriekš, mums var būt arī liels daudzums atmiņas, ko
esam dinamiski piešķīruši un nolasījuši no tās un ierakstām failā.
Un mums ir arī viens mainīgais, kas spēj saturēt vienu informācijas
baitu, piemēram, rakstzīmi.
Bet atkal mums ir jānodod šī mainīgā adrese, kad mēs vēlamies no tā
lasīt.
Lai mēs varētu ierakstīt informāciju, ko atrodam šajā adresē, faila
norādē, ptr.
Papildus tām, par kurām mēs šodien runājām, ir daudz citu lielisku
failu I/O funkciju, kas veic dažādas darbības.
Daži no tiem, kas varētu būt noderīgi, ir fgets un fputs, kas ir
līdzvērtīgi fgetc un fputc, bet ir paredzēti vienas virknes lasīšanai
no faila.
Vienas rakstzīmes vietā tas nolasīs visu virkni.
fprintf, kas būtībā ļauj izmantot printf, lai rakstītu failā.
Tātad, tāpat kā jūs varat veikt mainīgo aizstāšanu, izmantojot
vietturus procenti i un procenti d utt., Tāpat ar printf varat ņemt
printf virkni un izdrukāt kaut ko līdzīgu failā.
fseek — ja jums ir DVD atskaņotājs, ir analoģija, ko es parasti
izmantoju šeit — tā ir līdzīga attīšanas un pārtīšanas pogu
izmantošanai, lai pārvietotos pa filmu.
Līdzīgi varat pārvietoties pa failu.
Viena no lietām šajā faila struktūrā, ko c jums izveido, ir rādītājs,
kas norāda, kurā faila vietā atrodaties.
Vai esat pašā sākumā, pie nulles baita?
Vai jums ir 100. baits, 1000. baits un tā tālāk?
Varat izmantot fseek, lai patvaļīgi pārvietotu šo indikatoru uz
priekšu vai atpakaļ.
Un ftell, atkal līdzīgs DVD atskaņotājam, ir kā mazs pulkstenis, kas
parāda, cik minūtes un sekundes atrodaties konkrētajā filmā.
Tāpat ftell norāda, cik baitu esat failā.
feof ir cita versija, kas ļauj noteikt, vai esat sasniedzis faila
beigas.
Un ferror ir funkcija, ko varat izmantot, lai noteiktu, vai,
strādājot ar failu, kaut kas nav noticis.
Atkal, tas ir tikai kā braukt pa virsu.
Standartā io.h joprojām ir daudz vairāk failu I/O funkciju.
Bet tas, iespējams, ļaus jums sākt strādāt ar failu norādēm.
Es esmu Dags Loids.
Šis ir cs50.