Kaip sukurti failą naudojant c. Įvesti duomenis iš failo ir išvesti į failą. Failų ir pakatalogių sąrašo gavimas

Šiame straipsnyje sužinosime, kaip skaityti duomenis iš failų ir įrašyti informaciją į failus C programose. Failai C naudojami C programos rezultatui išsaugoti ir naudoti jį paleidžiant iš naujo. Pavyzdžiui, galite išsaugoti skaičiavimo rezultatus ir žaidimo statistiką.
Norėdami dirbti su failais C, turite įtraukti stdio.h biblioteką
#įtraukti
Dirbti su failą C reikia nurodyti failo žymeklį pagal pavyzdį
FILE *failo žymeklio pavadinimas;
Pavyzdžiui
FILE *fin;
Nurodo peleko žymeklį į failą
Tada turite atidaryti failą ir susieti jį su failo žymekliu. Norėdami atidaryti failą C, kad galėtumėte skaityti, naudokite komandą
Failo žymeklio pavadinimas= fopen("failo kelias", "r");
Pavyzdžiui, ši komanda
fin = fopen("C:\\Vartotojai\\vartotojas\\Desktop\\data.txt", "r");
bus atidarytas failas data.txt, esantis darbalaukyje palei kelią C:\\Users\\user\\Desktop Norėdami sužinoti kelią į failą, galite pasirinkti failą pele, spustelėkite dešinį pelės mygtuką ir pasirinkite failo ypatybes. Skiltyje Vieta bus nurodytas failo kelias. Atkreipkite dėmesį, kad C kalboje kelias nurodomas dviem pasviraisiais brūkšniais.
Baigę dirbti su failu C, turite jį uždaryti naudodami komandą
fclose (failo žymeklio pavadinimas)

Informacijos skaitymas iš tekstinio failo C

Kad galėtumėte skaityti rusiškus simbolius iš failo, naudodami komandą turite sukonfigūruoti darbą su kirilica
setlocale(LC_ALL, "rusų kalba");

Tokiu atveju programos pradžioje turite įtraukti #include

fscanf() operatorius

Norėdami perskaityti žodį iš failą C naudojama komanda fscanf(). Ši komanda yra panaši į komandą, skirtą informacijos įvedimui iš klaviatūros, tik pirmasis parametras yra failo rodyklė
fscanf(failo rodyklė,"%duomenų įvesties formatas1% duomenų įvesties formatas2...",&kintamasis1,&kintamasis2...);
Pavyzdžiui, komanda
fscanf(fin,"%d%d%d",&a,&b,&c);
nuskaito trijų sveikųjų skaičių kintamųjų eilutę iš failo, susieto su failo žymeklio pele
Pažiūrėkime į pavyzdį programos, kuri nuskaito informaciją iš tekstinio failo data.txt, kuriame įrašyti trys skaičių stulpeliai ir įrašo į masyvus. Kiekvienas informacijos stulpelis turi savo masyvą. Išsami informacija apie.
#įtraukti
#įtraukti
pagrindinis ()
(int a;
int b;
int c;
int i;
// apibrėžkite failo žymeklį
FILE *fin;
// atidarykite failą skaitymui
fin = fopen("C:\\Vartotojai\\vartotojas\\Desktop\\data.txt", "r");
// eilutė po eilutės skaitymas iš failo
už (i=0;i<3;i++)
{
// eilutės skaitymas iš trijų failų reikšmių ir rašymas į masyvus
fscanf(fin,"%d%d%d",&a[i],&b[i],&c[i]);
}
// rodyti matricas ekrane
už (i=0;i<3;i++)
{
printf("%d %d %d ",a[i],b[i],c[i]);
}
getch();
// failo uždarymas
fclose(fin);
}

Informacijos nuskaitymas iš failo eilutėje po eilutės SI. Funkcija fgets ()

Operatorius fscanf() nuskaito žodį iš failo, t.y. į pirmą pasitaikiusią erdvę.
Norėdami perskaityti visą eilutę iš failo C, naudokite konstrukciją
if (NULL != fgets (eilutės kintamasis, eilutės ilgis, failo rodyklė))
{
veiksmai skaitant eilutę
}

Pavyzdžiui, C programa, kuri nuskaito dvi eilutes iš failo ir parodo jas ekrane
#įtraukti
#įtraukti
#įtraukti
pagrindinis ()
{
// nustatyti eilutės kintamuosius
char st1;
char st2;
//apibūdinkite failo žymeklį
FILE *fin;
// nustatyti darbą su kirilicos abėcėle
setlocale(LC_ALL, "rusų kalba");
// atidarykite failą skaitymui
fin = fopen("C:\\duomenys.txt", "r");
// perskaitykite pirmąją failo eilutę
if (NULL ! = fgets (st1, 100, fin))
{
// rodyti eilutę ekrane
printf("%s ",st1);)
// perskaitykite antrą eilutę iš failo
if (NULL ! = fgets (st2, 100, fin))
{
// rodyti eilutę ekrane
printf("%s ",st2);)
// uždarykite failą skaitymui
fclose(fin);
}

Informacijos rašymas į tekstinį failą C

Norėdami įrašyti duomenis į failą C, turite atidaryti failą įrašymo režimu
Failo žymeklio pavadinimas= fopen("failo kelias", "w");
Norėdami rašyti į eilutę tekstiniame faile, naudokite komandą fprnitf(), kuri yra panaši į komandą C, tik pirmasis parametras yra failo rodyklė
fprintf (failo žymeklio pavadinimas "% įvesties formatas", kintamieji);
Pavyzdžiui, kintamojo a reikšmės įrašymas į failą out.txt
a=10;
fout = fopen ("C:\\Vartotojai\\vartotojas\\Desktop\\out.txt", "w");
fprintf(fout,"%d", a);

C programos, kuri prašo dviejų skaičių ir įrašo abu šiuos skaičius bei jų sumą į failą out.txt, pavyzdys

#įtraukti
#įtraukti

pagrindinis ()
(int a;
int b;
int c;
FILE *fout;
fout = fopen ("C:\\Vartotojai\\vartotojas\\Desktop\\out.txt", "w");
printf ("įveskite pirmąjį skaičių");
scanf("%d", &a);
printf ("įveskite antrą skaičių");
scanf("%d", &b);
c=a+b;
fprintf(fout,"%d %d %d",a,b,c);
getch();
fclose(fout);
}

Įvesties / išvesties mechanizmas, kurį sukūrė , neatitinka šiandien visuotinai priimto objektinio programavimo stiliaus, be to, jame labai naudojamos rodyklės operacijos, kurios laikomos potencialiai nesaugiomis šiuolaikinėse saugaus kodo vykdymo aplinkose. Alternatyva kuriant taikomąsias programas yra standartinių I/O klasių mechanizmas, kurį suteikia C++ kalbos standartas.

Failų atidarymas

Dažniausiai naudojamos klasės yra ifstream skaitymui, ofstream – rašymui ir fstream – failų keitimui.

Visos srieginės įvesties / išvesties klasės yra netiesiogiai išvestos iš bendro protėvio ios, visiškai paveldėdamos jos funkcionalumą. Taigi failo atidarymo režimą nurodo open_mode numeracijos tipo duomenų narys, kuris apibrėžiamas taip:

Enum open_mode ( programa, dvejetainis, in, out, trunc, ate );

Žemiau pateikiamos galimos vėliavų vertės ir jų paskirtis.

Pavyzdžiui, norėdami atidaryti failą, pavadintą test.txt ir nuskaityti duomenis dvejetaine forma, turėtumėte parašyti:

ifstream failas; file.open("test.txt", ios::in | ios::binary);

Loginis ARBA operatorius (|) leidžia sukurti režimą su bet kokiu vėliavėlių deriniu. Taigi, kad atidarydami failą pagal įrašą netyčia neperrašytumėte esamo failo tuo pačiu pavadinimu, turite naudoti šią formą:

Ne srautinis failas; file.open("test.txt", ios::out | ios::app);

Daroma prielaida, kad atitinkamas antraštės failas yra įtrauktas į projektą:

#įtraukti

Norėdami patikrinti, ar failas buvo sėkmingai atidarytas, galite naudoti konstrukciją

If (!file) ( //Failo atidarymo klaida)

Įtraukimo ir išgavimo operatoriai

Nepaisoma failų tvarkymo klasėse įtraukimo operatorius (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

Failas<< "Это строка текста";

Taip pat galite rašyti teksto eilutę dalimis:

Failas<< "Это " << "строка " << "текста";

Endl sakinys baigia eilutės įvestį karietos grįžimu:

Failas<< "Это строка текста" << endl;

Naudojant įtraukimo operatorių, į failą lengva įrašyti kintamųjų ar masyvo elementų reikšmes:

Srautinio failo („Temp.txt“); char buff = "Teksto masyve yra kintamųjų"; int vx = 100; float pi = 3,14159; failą<< buff << endl << vx << endl << pi << endl;

Vykdant kodą susidaro trys tekstinio failo Temp.txt eilutės:

Teksto masyve yra kintamieji 100 3.14159

Atminkite, kad skaitinės reikšmės į failą įrašomos kaip tekstinės eilutės, o ne dvejetainės reikšmės.

Paėmimo operatorius(>>) sukelia priešingą efektą. Atrodytų, kad norėdami išgauti simbolius iš anksčiau parašyto Temp.txt failo, turėtumėte parašyti tokį kodą:

Ifstream failas ("Temp.txt"); char buff; int vx; float pi; failas >> buff >> vx >> pi;

Tačiau ištraukimo operatorius sustos ties pirmuoju skiriamuoju ženklu (tarpo, tabuliavimo ar naujos eilutės). Taigi, analizuojant sakinį „Teksto masyve yra kintamųjų“, į buff masyvą bus įrašytas tik žodis „Tekstas“, tarpas nepaisomas, o žodis „masyvas“ taps viso vx kintamojo reikšme, o kodas Vykdymas „suklys“ dėl neišvengiamo duomenų struktūros pažeidimo. Toliau, aptardami ifstream klasę, parodysime, kaip tinkamai organizuoti failo skaitymą iš ankstesnio pavyzdžio.

ifstream klasė: failų skaitymas

Kaip rodo pavadinimas, ifstream klasė skirta įvesti failo srautą. Pagrindiniai klasės metodai yra išvardyti žemiau. Dauguma jų yra paveldėti iš istream klasės ir perkrauti, kad būtų išplėstos pagrindinės funkcijos. Pavyzdžiui, funkcija get, priklausomai nuo iškvietimo parametro, gali nuskaityti ne tik vieną simbolį, bet ir simbolių bloką.

Dabar aišku, kaip reikia modifikuoti ankstesnį pavyzdį, kad naudojant duomenų ištraukimo operatorių būtų gautas laukiamas rezultatas:

Ifstream failas ("Temp.txt"); char buff; int vx; float pi; file.getline(buff, sizeof(buff)); failas >> vx >> pi:

Getline metodas nuskaitys pirmąją failo eilutę iki galo, o operatorius >> priskirs reikšmes kintamiesiems.

Šiame pavyzdyje parodytas duomenų įtraukimas į tekstinį failą ir viso failo skaitymas. Ciklas while(1) naudojamas vietoj while(!file2.eof()) dėl priežasčių, aptartų .

#įtraukti #įtraukti naudojant vardų sritį std; int main() ( ofstream failas; file.open("test.txt",ios::out|ios::app); if (!file) ( cout<< "File error - can"t open to write data!"; cin.sync(); cin.get(); return 1; } for (int i=0; i<10; i++) file << i << endl; file.close(); ifstream file2; file2.open("test.txt", ios::in); if (!file2) { cout << "File error - can"t open to read data!"; cin.sync(); cin.get(); return 2; } int a,k=0; while (1) { file2 >>a; if (file2.eof()) break; cout<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

Šiame pavyzdyje parodyta kilpa, kuri nuskaito eilutes iš failo test.txt ir rodo jas konsolėje.

#įtraukti #įtraukti naudojant vardų sritį std; int main() ( ifstream failas; // sukurti srauto objekto failą file.open("test.txt"); // atidaryti failą skaitymui if (!file) return 1; // grįžti atidarius klaida char str; // statinis eilučių buferis // Skaityti ir rodyti eilutes cikle, kol eof while (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

Šis kodas Windows OS taip pat priklauso nuo naujos eilutės simbolio buvimo paskutinėje failo eilutėje; būtų patikimiau tai padaryti:

Nors (1) ( if (file.eof()) pertrauka; file.getline(str, sizeof(str)); cout<< str << endl; }

Aiškiai iškviesti atviro ir uždarymo metodus nereikia. Iš tiesų, iškvietus konstruktorių su argumentu, failą galima atidaryti iš karto, kai sukuriamas sriegiuoto failo objektas:

Ifstream failas ("test.txt");

Vietoj uždarymo metodo galite naudoti trynimo operatorių, kuris automatiškai iškvies failo objekto naikintuvą ir uždarys failą. Nors ciklo kodas užtikrina tinkamą failo pabaigos patikrinimą.

ofstream klasė: failų rašymas

Srautinio srauto klasė skirta išvesti duomenis iš failų srauto. Toliau pateikiami pagrindiniai šios klasės metodai.

Anksčiau aprašytas įtraukimo operatorius yra patogus organizuojant rašymą į tekstinį failą:

Srautinio failo („temp.txt“); if (!file) return; už (int i=1; i<=3; i++) file << "Строка " << i << endl; file.close();

Dvejetainiai failai

Iš esmės dvejetainiai duomenys traktuojami kaip tekstiniai duomenys. Skirtumas tas, kad jei dvejetainiai duomenys rašomi tam tikroje loginėje struktūroje, tai jie turi būti nuskaitomi iš failo į to paties struktūros tipo kintamąjį.

Pirmasis rašymo ir skaitymo metodų parametras (rašymo/skaitymo bloko adresas) turi būti simbolio rodyklės tipo char * , todėl būtina atlikti aiškų void * struktūros adreso tipo konvertavimą. Antrasis parametras nurodo, kad failo dvejetainiai blokai turi pastovų baitų dydį, neatsižvelgiant į faktinį įrašo ilgį. Šioje programoje pateikiamas duomenų kūrimo ir rodymo paprastoje užrašų knygelėje pavyzdys. Tada failų įrašai skaitomi paeiliui ir rodomi konsolėje.

#įtraukti #įtraukti #įtraukti naudojant vardų sritį std; struct Pastabos ( // bloknoto duomenų struktūra char Vardas; // visas vardas char Telefonas; // telefonas int Amžius; // amžius ); int main() ( setlocale(LC_ALL, "rusų kalba"); Pastabos Note1= ("Siaubingas Jonas Vasiljevičius", "neįdiegtas", 60 ); Pastabos Note2= ("Godunovas Borisas Fedorovičius", "095-111-2233" , 30 ); Pastabos Note3= ( "Romanovas Petras Michailovičius ", "812-333-2211 ", 20 ); ofstream ofile("Notebook.dat", ios::binary); ofile.write((char*)&Note1, sizeof (Notes)); // 1-as blokas ofile.write((char*)&Note2, sizeof(Notes)); // 2-as blokas ofile.write((char*)&Note3, sizeof(Notes)); / / 3-ias blokas ofile.close(); // uždarykite įrašytą failą ifstream ifile ("Notebook.dat", ios::binary); Pastabos Pastaba; // struktūrinis kintamasis char str; // statinis eilutės buferis // Skaitykite ir rodykite eilutes kilpa iki eof while (!ifile.read((char*)&Note, sizeof(Notes)).eof()) ( sprintf(str, "%s\tPhone: %s\tAge: %d" , Note.Name, Pastaba.Telefonas, Pastaba.Amžius); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

Vykdant šį kodą dvejetainis failas Notebook.dat susidaro iš trijų blokų po 80 baitų (darant prielaidą, kad simboliai yra vieno baito). Natūralu, kad galite naudoti kitus gijų kūrimo metodus ir atlikti bet kokias operacijas konkrečios duomenų struktūros laukuose.

fstream klasė: atsitiktinė prieiga prie failų

Tarkime, kad mūsų sąsiuvinyje yra 100 įrašų, o mes norime suskaičiuoti 50. Žinoma, galite organizuoti kilpą ir skaityti visus įrašus nuo pirmojo iki pateikto. Akivaizdu, kad tikslingesnis sprendimas yra nustatyti pos failo padėties žymeklį tiesiai į 50 įrašą ir skaityti iš jo:

Ifstream ifile("Notebook.dat", ios::binary); int poz = 49 * sizeof(Pastabos); ifile.seekg(pos); // ieškoti įrašo 50th Notes Note; //Pastabos – aukščiau aprašyta „įrašo“ struktūra ifile.read((char*)&Note, sizeof(Notes));

Tokios paieškos operacijos yra veiksmingos, jei failą sudaro žinomo ir pastovaus dydžio įrašai. Norėdami pakeisti savavališko įrašo turinį, turite atidaryti išvesties srautą modifikavimo režimu:

„Ofstream ofile“ („Notebook.dat“, ios::binary | ios::ate); int poz = 49 * sizeof(Pastabos); ofile seekp(pos); // ieškoti 50-osios natos Notes Note50 = ("Jelcinas Borisas Nikolajevičius", "095-222-3322", 64); ofile.write((char*)&Pastaba, dydis(Pastabos)); // pakeitimas

Jei nenurodysite ios::ate (arba ios::app) vėliavėlės, atidarius dvejetainį failą Notebook.dat, ankstesnis jo turinys bus ištrintas!

Galiausiai galima vienu metu atidaryti failą skaitymui / rašymui, naudojant metodus, kuriuos fstream srautinio perdavimo klasė paveldėjo iš savo pirmtakų. Kadangi fstream klasė yra kilusi iš istream ir ostream (atitinkamai ifstream ir ofstream tėvai), visi anksčiau paminėti metodai tampa prieinami programoje.

Šiame pavyzdyje parodytas pirmojo ir trečiojo failo Notebook.dat įrašų pertvarkymas.

#įtraukti #įtraukti #įtraukti naudojant vardų sritį std; struct Pastabos (char Vardas; char Telefonas; int Amžius; ); int main() ( setlocale(LC_ALL, "rusų kalba"); Notes Note1, Note3; // Atidarykite failą, kad galėtumėte skaityti / rašyti vienu metu fstream file ("Notebook.dat", ios::binary | ios::in | ios: : out); file.seekg(2 * sizeof(Notes)); // rasti ir skaityti Note3 file.read((char*)&Note3, sizeof(Notes)); file.seekg(0); // rasti ir skaityti Note1 file.read((char*)&Note1, sizeof(Notes)); file.seekg(0); // Note1<== Note3 file.write((char*)&Note3, sizeof(Notes)); file.seekg(2 * sizeof(Notes)); // Note3 <== Note1 file.write((char*)&Note1, sizeof(Notes)); char str; // Считывать и отображать записи в цикле, пока не eof file.seekg(0); // вернуться к началу файла while (!file.read((char*)&Note1, sizeof(Notes)).eof()) { sprintf(str, "%s\tТел: %s\tВозраст: %d", Note1.Name, Note1.Phone, Note1.Age); cout << str << endl; } file.close(); cin.sync(); cin.get(); return 0; }

Failo objekto konstruktoriuje turite nurodyti ios::in ir ios::out vėliavėles, leidžiančias vienu metu atlikti skaitymo ir rašymo operacijas. Vykdant šį kodą, pirmasis ir trečiasis dvejetainio failo Notebook.dat įrašai bus sukeisti.

Yra papildomų pavyzdžių šia tema.

Anksčiau įvesdami ir išvesdami duomenis dirbome su standartiniais srautais – klaviatūra ir monitoriumi. Dabar pažiūrėkime, kaip C kalba priima duomenis iš failų ir įrašo juos ten. Prieš atlikdami šias operacijas, turite atidaryti failą ir jį pasiekti.

C programavimo kalboje rodyklė į failą yra FILE tipo, o jo deklaracija atrodo taip:
FILE *mano failas;

Kita vertus, funkcija fopen () atidaro failą adresu, nurodytu kaip pirmasis argumentas skaitymo („r“), rašymo („w“) arba pridėjimo („a“) režimu ir grąžina į jį žymeklį. prie programos. Todėl failo atidarymo ir prijungimo prie programos procesas atrodo maždaug taip:
mano failas = fopen("labas.txt", "r");

Skaitant arba įrašant duomenis į failą, prie jo pasiekiama per failo žymeklį (šiuo atveju mano failas).

Jei dėl vienokių ar kitokių priežasčių (nurodytu adresu failo nėra, prieiga prie jo uždrausta) funkcija fopen() negali atidaryti failo, tada ji grąžina NULL. Realiose programose jie beveik visada apdoroja failo atidarymo klaidą if šakoje, bet mes to praleisime.

Funkcijos fopen() deklaracija yra stdio.h antraštės faile, todėl ji turi būti įtraukta. Taip pat stdio.h yra deklaruojamas struktūros tipas FILE.

Baigus darbą su failu, įprasta jį uždaryti, kad buferis būtų atlaisvintas nuo duomenų ir dėl kitų priežasčių. Tai ypač svarbu, jei programa ir toliau veikia po darbo su failu. Ryšys tarp išorinio failo ir programos rodyklės į jį nutraukiamas naudojant fclose() funkciją. Rodyklė į failą perduodama kaip parametras:
fclose(mano failas);

Programoje galima atidaryti daugiau nei vieną failą. Tokiu atveju kiekvienas failas turi būti susietas su savo failo žymekliu. Tačiau jei programa pirmiausia dirba su vienu failu, o po to jį uždaro, tada žymeklį galima naudoti norint atidaryti antrą failą.

Skaitymas iš tekstinio failo ir rašymas į jį

fscanf()

Fscanf () funkcija yra panaši į funkciją scanf (), tačiau skirtingai nuo jos, ji pateikia formatuotą įvestį iš failo, o ne standartinę įvestį. Fscanf() funkcija paima parametrus: failo žymeklį, formato eilutę, atminties sričių adresus duomenims rašyti:
fscanf(mano failas, "%s%d", str, &a);

Grąžina sėkmingai nuskaitytų duomenų arba EOF skaičių. Tarpai ir naujos eilutės simboliai skaičiuojami kaip duomenų skyrikliai.

Tarkime, kad turime failą, kuriame yra toks objektų aprašymas:

Obuoliai 10 23,4 bananai 5 25,0 duona 1 10,3

#įtraukti main () ( FILE * failas; struct food ( char pavadinimas[ 20 ] ; nepasirašytas kiekis; plaukiojanti kaina; ) ; struct food shop[ 10 ] ; char i= 0 ; failas = fopen ( "fscanf.txt", "r" ) ; while (fscanf (failas, "%s%u%f" , shop[ i].name , & (shop[ i].qty ) , & (shop[ i].price ) ) != EOF) ( printf ("%s %u %.2f \n", parduotuvė[ i].pavadinimas, parduotuvė[ i].v., parduotuvė[ i].kaina) ; i++; ) )

Šiuo atveju deklaruojama struktūra ir struktūrų masyvas. Kiekviena failo eilutė atitinka vieną masyvo elementą; masyvo elementas yra struktūra, kurią sudaro eilutė ir du skaitmeniniai laukai. Ciklas skaito vieną eilutę per iteraciją. Kai aptinkama failo pabaiga, fscanf() grąžina EOF ir ciklas baigiasi.

fgets ()

Fgets() funkcija yra panaši į gets() funkciją ir atlieka eilutę po eilutės įvestį iš failo. Vienas iškvietimas į fgets() nuskaitys vieną eilutę. Tokiu atveju galite perskaityti ne visą eilutę, o tik dalį jos nuo pat pradžių. fgets() parametrai atrodo taip:
fgets (simbolių_masyvas, perskaitytų_simbolių_skaičius, rodyklė_į_failą)

Pavyzdžiui:
fgets (str, 50, mano failas)

Šis funkcijos iškvietimas iš failo, susieto su mano failo žymekliu, nuskaitys vieną visą teksto eilutę, jei jos ilgis yra mažesnis nei 50 simbolių, įskaitant simbolį „\n“, kurį funkcija taip pat išsaugos masyve. Paskutinis (50-asis) str masyvo elementas bus simbolis „\0“, pridėtas fgets() . Jei eilutė ilgesnė, funkcija skaitys 49 simbolius ir pabaigoje parašys „\0“. Tokiu atveju „\n“ skaitymo eilutėje nebus.

#įtraukti #define N 80 main () ( FILE * failas; char arr[ N] ; failas = fopen ( "fscanf.txt", "r") ; while (fgets (arr, N, failas) != NULL) printf (" %s" , arr) ; printf (" \n") ; fclose(failas); )

Šioje programoje, skirtingai nei ankstesnėje, duomenys eilutė po eilutės skaitomi į masyvą. Kai skaitoma kita eilutė, ankstesnė prarandama. Fgets() funkcija grąžina NULL, jei negali nuskaityti kitos eilutės.

getc() arba fgetc()

Funkcija getc() arba fgetc() (abi veikia) leidžia iš failo gauti kitą vieną simbolį.

while ((arr[ i] = fgetc (failas) ) != EOF) ( if (arr[ i] == " \n") (arr[i] = " \0 " ; printf("%s \n", arr) ; i = 0; ) kitaip i++; )arr[i] = " \0 " ; printf("%s \n", arr) ;

Pavyzdinis kodas rodo duomenis iš failo ekrane.

Rašymas į tekstinį failą

Kaip ir įvestis, išvestis į failą gali būti skirtinga.

  • Suformatuota išvestis. Funkcija fprintf (failo_indeksas, formato_eilutė, kintamieji) .
  • Išvestis po eilutės. Funkcija fputs(string, file_pointer) .
  • Išvestis po simbolio. Funkcija fputc() arba putc(simbolis, failo_rodiklis) .

Žemiau pateikiami kodo pavyzdžiai, kuriuose naudojami trys duomenų išvedimo į failą metodai.

Vienos struktūros laukų įrašymas į kiekvieną failo eilutę:

failas = fopen ("fprintf.txt" , "w" ) ; while (scanf ("%s%u%f" , shop[ i].name , & (shop[ i].qty ) , & (shop[ i].price ) ) != EOF) ( fprintf (failas, " %s %u %.2f \n", parduotuvė[ i].pavadinimas, parduotuvė[ i].v., parduotuvė[ i].kaina) ; i++; )

Eilutė po eilutės išvestis į failą (fputs(), skirtingai nei pats puts(), eilutės pabaigoje nededa „\n“):

while (gets (arr) != NULL) ( fputs (arr, file); fputs (" \n", failas); )

Išvesties po simbolio pavyzdys:

while ((i = getchar () ) != EOF) putc (i, failas) ;

Skaitymas iš dvejetainio failo ir rašymas į jį

Su failu galite dirbti ne kaip simbolių seka, o kaip baitų seka. Iš esmės su netekstiniais failais dirbti kitaip negalima. Tačiau tokiu būdu galite skaityti ir rašyti tekstinius failus. Šio failo prieigos būdo privalumas yra skaitymo ir rašymo greitis: per vieną prieigą galima nuskaityti / įrašyti didelį informacijos bloką.

Atidarant dvejetainės prieigos failą, antrasis fopen() parametras yra eilutė „rb“ arba „wb“.

Darbo su dvejetainiais failais tema yra gana sudėtinga ir norint ją ištirti, reikia atskiros pamokos. Čia bus pažymėtos tik failo, kuris laikomas baitų srautu, skaitymo ir rašymo į jį funkcijų ypatybės.

Funkcijos fread() ir fwrite() laikomos parametrais:

  1. atminties srities, iš kurios įrašomi arba nuskaitomi duomenys, adresas,
  2. bet kokio tipo dydis,
  3. nurodyto dydžio nuskaitytų duomenų kiekis,
  4. failų indeksas.

Šios funkcijos grąžina sėkmingai perskaitytų arba įrašytų duomenų skaičių. Tie. galite „užsakyti“ nuskaityti 50 duomenų elementų, bet gauti tik 10. Klaidos nebus.

Funkcijų fread() ir fwrite() naudojimo pavyzdys:

#įtraukti #įtraukti main () ( FILE * failas; char shelf1 [ 50 ], shelf2 [ 100 ] ; int n, m; file = fopen ("shelf1.txt" , "rb" ) ; n = fread (shelf1, sizeof (char ) , 50 , failas) ; fclose (failas) ; failas = fopen ("shelf2.txt" , "rb" ) ; m = fread (shelf2, sizeof (char ) , 50 , file) ; fclose (failas) ; lentyna1[ n] = " \0 " ; lentyna2 [m] = " \n"; lentyna2 [ m+ 1 ] = " \0 " ; failas = fopen ("shop.txt" , "wb" ) ; fwrite (strcat (shelf2, shelf1) , sizeof (char ) , n+ m, failas) ; fclose(failas); )

Čia bandoma nuskaityti 50 simbolių iš pirmojo failo. n saugo faktiškai perskaitytų simbolių skaičių. n reikšmė gali būti 50 arba mažesnė. Duomenys dedami į eilutę. Tas pats atsitinka su antruoju failu. Tada pirmoji eilutė pridedama prie antrosios, o duomenys iškeliami į trečiąjį failą.

Problemų sprendimas

  1. Parašykite programą, kuri paklausia vartotojo tekstinio failo pavadinimo (adreso), tada jį atidaro ir suskaičiuoja jame esančių simbolių ir eilučių skaičių.
  2. Parašykite programą, kuri įrašo į failą duomenis, gautus iš kito failo ir kokiu nors būdu pakeistą prieš rašant. Kiekviena duomenų eilutė, gauta iš failo, turi tilpti į struktūrą.

Kad būtų lengviau pasiekti, informacija saugojimo įrenginiuose saugoma failų pavidalu.

Failas yra pavadinta išorinės atminties sritis, skirta duomenų masyvo saugojimui. Failuose esantys duomenys yra labai įvairaus pobūdžio: programos algoritmine arba mašinine kalba; pradiniai programos veikimo duomenys arba programos vykdymo rezultatai; nemokami tekstai; grafiniai vaizdai ir kt.

Katalogas (aplankas, katalogas) - pavadintas baitų rinkinys laikmenoje, kuriame yra pakatalogių ir failų pavadinimai, naudojamas failų sistemoje, siekiant supaprastinti failų organizavimą.

Failų sistema vadinama funkcine operacinės sistemos dalimi, kuri atlieka operacijas su failais. Failų sistemų pavyzdžiai yra FAT (FAT – failų paskirstymo lentelė), NTFS, UDF (naudojami kompaktiniuose diskuose).

Yra trys pagrindinės FAT versijos: FAT12, FAT16 ir FAT32. Jie skiriasi disko struktūros įrašų bitų gyliu, t.y. bitų skaičius, skirtas saugoti klasterio numerį. FAT12 daugiausia naudojamas diskeliams (iki 4 KB), FAT16 - mažos talpos diskams, FAT32 - didelės talpos FLASH diskams (iki 32 GB).

Pažvelkime į failų sistemos struktūrą, kaip pavyzdį naudodami FAT32.

FAT32 failo struktūra

Išoriniai FAT32 sistemos atminties įrenginiai turi blokų, o ne baitų adresavimą. Informacija įrašoma į išorinį atminties įrenginį blokais arba sektoriais.

Sektorius yra minimalus adresuojamas informacijos saugojimo išoriniuose saugojimo įrenginiuose vienetas. Paprastai sektoriaus dydis yra fiksuotas 512 baitų. Siekiant padidinti išorinių atminties įrenginių adresų erdvę, sektoriai sujungiami į grupes, vadinamas klasteriais.

Klasteris yra kelių sektorių sąjunga, kurią galima laikyti savarankišku vienetu, turinčiu tam tikrų savybių. Pagrindinė klasterio savybė yra jo dydis, matuojamas sektorių skaičiumi arba baitų skaičiumi.

FAT32 failų sistema turi tokią struktūrą.

Failų rašymui naudojami klasteriai numeruojami nuo 2. Klasterį Nr. 2 paprastai naudoja šakninis katalogas, o nuo 3 klasterio saugomas duomenų masyvas. Sektoriai, naudojami informacijai saugoti virš šakninio katalogo, nėra sugrupuoti.
Mažiausias reikalingo failo dydis diske atitinka 1 klasterį.

Įkrovos sektorius prasideda tokia informacija:

  • EB 58 90 – besąlyginis šuolis ir parašas;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 – baitų skaičius sektoriuje (dažniausiai 512);
  • 1 baitas – sektorių skaičius klasteryje;
  • 2 baitai – rezervinių sektorių skaičius.

Be to, įkrovos sektoriuje yra ši svarbi informacija:

  • 0x10 (1 baitas) – FAT lentelių skaičius (dažniausiai 2);
  • 0x20 (4 baitai) – sektorių skaičius diske;
  • 0x2С (4 baitai) – šakninio katalogo klasterio numeris;
  • 0x47 (11 baitų) – tūrio etiketė;
  • 0x1FE (2 baitai) – įkrovos sektoriaus parašas (55 AA).

Failų sistemos informacijos sektoriuje yra:

  • 0x00 (4 baitai) – parašas (52 52 61 41);
  • 0x1E4 (4 baitai) – parašas (72 72 41 61);
  • 0x1E8 (4 baitai) – laisvų klasterių skaičius, -1, jei nežinoma;
  • 0x1EC (4 baitai) – paskutinio įrašyto klasterio numeris;
  • 0x1FE (2 baitai) – parašas (55 AA).

FAT lentelėje yra informacija apie kiekvienos grupės diske būseną. Apatiniai 2 FAT lentelės baitai saugo F8 FF FF 0F FF FF FF FF (tai atitinka 0 ir 1 grupių būseną, kurių fiziškai nėra). Toliau kiekvienos klasterio būsenoje yra klasterio, kuriame tęsiasi dabartinis failas, numeris arba ši informacija:

  • 00 00 00 00 – klasteris nemokamas;
  • FF FF FF 0F – esamo failo pabaiga.
  • 8 baitai – failo pavadinimas;
  • 3 baitai – failo plėtinys;

Šakniniame kataloge yra 32 bitų informacijos įrašų rinkinys apie kiekvieną failą, kuriame yra ši informacija:

Dirbant su ilgais failų pavadinimais (įskaitant rusiškus), failo pavadinimas užkoduojamas naudojant UTF-16 kodavimo sistemą. Šiuo atveju kiekvienam simboliui koduoti skiriami 2 baitai. Šiuo atveju failo pavadinimas rašomas tokia struktūra:

  • 1 sekos baitas;
  • 10 baitų yra 5 apatiniai failo pavadinimo simboliai;
  • 1 baito atributas;
  • 1 baitas rezervuotas;
  • 1 baitas – DOS vardo kontrolinė suma;
  • 12 baitų yra 3 apatiniai failo pavadinimo simboliai;
  • 2 baitai – pirmo klasterio numeris;
  • likusieji ilgojo vardo simboliai.

Darbas su failais C kalba

Programuotojui atidarytas failas yra vaizduojamas kaip skaitomų arba įrašomų duomenų seka. Kai failas atidaromas, jis susiejamas su I/O srautas. Išvesties informacija įrašoma į srautą, įvesties informacija nuskaitoma iš srauto.

Kai srautas atidaromas I/O, jis susiejamas su standartine FILE struktūra, kuri apibrėžta stdio.h. FILE struktūroje yra reikalinga informacija apie failą.

Failas atidaromas naudojant funkciją fopen(), kuri grąžina žymeklį į FILE struktūrą, kurią galima naudoti tolimesnėms failo operacijoms.

FAILAS *fopen(vardas, tipas);


pavadinimas – atidaromo failo pavadinimas (įskaitant kelią),
tipas yra žymeklis į simbolių eilutę, kuri apibrėžia, kaip failas pasiekiamas:
  • "r" - atidarykite failą skaitymui (failas turi egzistuoti);
  • "w" - atidarykite tuščią failą rašymui; jei failas egzistuoja, jo turinys prarandamas;
  • "a" - atidarykite failą rašymui iki galo (pridėjimui); failas sukuriamas, jei jo nėra;
  • "r+" - atidarykite failą skaitymui ir rašymui (failas turi egzistuoti);
  • "w+" - atidarykite tuščią failą skaitymui ir rašymui; jei failas egzistuoja, jo turinys prarandamas;
  • "a+" - atidarykite failą skaitymui ir pridėjimui; jei failo nėra, tada jis sukuriamas.

Grąžinama vertė yra rodyklė į atvirą srautą. Jei įvyksta klaida, grąžinama NULL.

Funkcija fclose() uždaro srautą ar srautus, susietus su failais, atidarytais naudojant funkciją fopen(). Uždaromas srautas nustatomas pagal funkcijos fclose() argumentą.

Grąžinama reikšmė: vertė 0, jei srautas buvo sėkmingai uždarytas; pastovus EOF, jei įvyko klaida.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#įtraukti
int main() (
FILE *fp;
char pavadinimas = "mano.txt" ;
if ((fp = fopen(vardas, "r" )) == NULL )
{
printf( "Nepavyko atidaryti failo");
getchar ();
grąžinti 0;
}
// pavyko atidaryti failą
... // būtini veiksmai su duomenimis
fclose(fp);
getchar ();
grąžinti 0;
}

Simbolio skaitymas iš failo:

char fgetc(srautas);


Funkcijos argumentas yra rodyklė į FILE tipo srautą. Funkcija grąžina perskaityto simbolio kodą. Jei pasiekiama failo pabaiga arba įvyksta klaida, grąžinamas pastovus EOF.

Simbolio įrašymas į failą:

fputc(char, srautas);

Funkcijos argumentai yra simbolis ir rodyklė į FILE tipo srautą. Funkcija grąžina perskaityto simbolio kodą.

Funkcijos fscanf() ir fprintf() yra panašios į scanf() ir printf() funkcijas, tačiau veikia su duomenų failais ir jų pirmasis argumentas yra failo žymeklis.

fscanf(stream, "InputFormat", argumentai);