Uri ng data ng file c. Paggawa gamit ang mga text file sa C

Para sa kadalian ng pag-access, ang impormasyon sa mga storage device ay iniimbak sa anyo ng mga file.

Ang isang file ay isang pinangalanang lugar ng panlabas na memorya na inilaan para sa pag-iimbak ng isang hanay ng data. Ang data na nakapaloob sa mga file ay napaka-magkakaibang kalikasan: mga programa sa algorithmic o machine language; paunang data para sa pagpapatakbo ng programa o mga resulta ng pagpapatupad ng programa; libreng mga teksto; mga graphic na larawan, atbp.

Direktoryo (folder, direktoryo) - isang pinangalanang koleksyon ng mga byte sa isang storage medium na naglalaman ng mga pangalan ng mga subdirectory at file, na ginagamit sa file system upang gawing simple ang organisasyon ng mga file.

Sistema ng file tinatawag na functional na bahagi ng operating system na nagsasagawa ng mga operasyon sa mga file. Ang mga halimbawa ng mga file system ay FAT (FAT - File Allocation Table), NTFS, UDF (ginamit sa mga CD).

Mayroong tatlong pangunahing bersyon ng FAT: FAT12, FAT16 at FAT32. Nag-iiba sila sa bit depth ng mga tala sa istraktura ng disk, i.e. ang bilang ng mga bit na inilaan upang iimbak ang numero ng kumpol. Ang FAT12 ay pangunahing ginagamit para sa mga floppy disk (hanggang sa 4 KB), FAT16 - para sa mga disk na may maliit na kapasidad, FAT32 - para sa mga high-capacity na FLASH drive (hanggang sa 32 GB).

Tingnan natin ang istraktura ng file system gamit ang FAT32 bilang isang halimbawa.

Ang istraktura ng file ng FAT32

Ang mga external na memory device sa FAT32 system ay may block addressing sa halip na byte addressing. Ang impormasyon ay nakasulat sa isang panlabas na memorya ng aparato sa mga bloke o sektor.

Ang sektor ay ang pinakamababang natutugunan na yunit ng imbakan ng impormasyon sa mga panlabas na storage device. Karaniwan, ang laki ng sektor ay naayos sa 512 bytes. Upang madagdagan ang espasyo ng address ng mga external na memory device, pinagsama-sama ang mga sektor sa mga pangkat na tinatawag na mga kumpol.

Ang cluster ay isang unyon ng ilang sektor, na maaaring ituring bilang isang independiyenteng yunit na may ilang partikular na katangian. Ang pangunahing katangian ng isang cluster ay ang laki nito, na sinusukat sa bilang ng mga sektor o bilang ng mga byte.

Ang FAT32 file system ay may sumusunod na istraktura.

Ang mga cluster na ginagamit para sa pagsusulat ng mga file ay binibilang simula sa 2. Bilang isang panuntunan, ang cluster No. 2 ay ginagamit ng root directory, at simula sa cluster No. 3 ang data array ay iniimbak. Ang mga sektor na ginamit upang mag-imbak ng impormasyon sa itaas ng root directory ay hindi naka-cluster.
Ang minimum na laki ng file na kinakailangan sa disk ay tumutugma sa 1 cluster.

Ang boot sector ay nagsisimula sa sumusunod na impormasyon:

  • EB 58 90 – walang kondisyong pagtalon at lagda;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 – bilang ng mga byte sa sektor (karaniwan ay 512);
  • 1 byte – bilang ng mga sektor sa cluster;
  • 2 bytes - bilang ng mga reserbang sektor.

Bilang karagdagan, ang sektor ng boot ay naglalaman ng sumusunod na mahalagang impormasyon:

  • 0x10 (1 byte) – bilang ng mga FAT table (karaniwan ay 2);
  • 0x20 (4 bytes) - bilang ng mga sektor sa disk;
  • 0x2С (4 bytes) - numero ng kumpol ng direktoryo ng ugat;
  • 0x47 (11 bytes) – label ng volume;
  • 0x1FE (2 bytes) – lagda ng sektor ng boot (55 AA).

Ang sektor ng impormasyon ng file system ay naglalaman ng:

  • 0x00 (4 bytes) – lagda (52 52 61 41);
  • 0x1E4 (4 bytes) – lagda (72 72 41 61);
  • 0x1E8 (4 bytes) – bilang ng mga libreng cluster, -1 kung hindi alam;
  • 0x1EC (4 bytes) – bilang ng huling naitalang kumpol;
  • 0x1FE (2 byte) – lagda (55 AA).

Ang talahanayan ng FAT ay naglalaman ng impormasyon tungkol sa estado ng bawat kumpol sa disk. Ang mas mababang 2 byte ng FAT table ay nag-iimbak ng F8 FF FF 0F FF FF FF FF (na tumutugma sa estado ng mga cluster 0 at 1, na pisikal na wala). Susunod, ang estado ng bawat cluster ay naglalaman ng bilang ng cluster kung saan nagpapatuloy ang kasalukuyang file o ang sumusunod na impormasyon:

  • 00 00 00 00 – libre ang cluster;
  • FF FF FF 0F – dulo ng kasalukuyang file.
  • 8 bytes - pangalan ng file;
  • 3 bytes - extension ng file;

Ang root directory ay naglalaman ng isang set ng 32-bit na mga tala ng impormasyon tungkol sa bawat file, na naglalaman ng sumusunod na impormasyon:

Kapag nagtatrabaho sa mahabang pangalan ng file (kabilang ang mga pangalan ng Ruso), ang pangalan ng file ay naka-encode gamit ang UTF-16 encoding system. Sa kasong ito, 2 byte ang inilalaan para sa pag-encode ng bawat character. Sa kasong ito, ang pangalan ng file ay nakasulat sa sumusunod na istraktura:

  • 1 sequence byte;
  • Ang 10 byte ay naglalaman ng mas mababang 5 character ng pangalan ng file;
  • 1 byte na katangian;
  • 1 byte ang nakalaan;
  • 1 byte – checksum ng pangalan ng DOS;
  • Ang 12 byte ay naglalaman ng mas mababang 3 character ng pangalan ng file;
  • 2 bytes - bilang ng unang kumpol;
  • ang natitirang mga character ng mahabang pangalan.

Paggawa gamit ang mga file sa wikang C

Para sa programmer, ang isang bukas na file ay kinakatawan bilang isang sequence ng data na binabasa o isinusulat. Kapag ang isang file ay binuksan, ito ay nauugnay sa I/O stream. Ang impormasyon ng output ay nakasulat sa stream, ang impormasyon ng input ay binabasa mula sa stream.

Kapag ang isang stream ay binuksan para sa I/O, ito ay nauugnay sa isang karaniwang FILE na istraktura, na tinukoy sa stdio.h. Ang istraktura ng FILE ay naglalaman ng kinakailangang impormasyon tungkol sa file.

Ang pagbubukas ng isang file ay ginagawa gamit ang fopen() function, na nagbabalik ng isang pointer sa isang istraktura ng uri ng FILE na maaaring magamit para sa mga kasunod na operasyon sa file.

FILE *fopen(pangalan, uri);


pangalan – pangalan ng file na bubuksan (kabilang ang landas),
Ang uri ay isang pointer sa isang string ng mga character na tumutukoy kung paano naa-access ang file:
  • "r" - buksan ang file para sa pagbabasa (dapat na umiiral ang file);
  • "w" - buksan ang isang walang laman na file para sa pagsusulat; kung umiiral ang file, mawawala ang mga nilalaman nito;
  • "a" - buksan ang file para sa pagsusulat hanggang sa dulo (para sa pagdaragdag); ang file ay nilikha kung wala ito;
  • "r+" - buksan ang file para sa pagbabasa at pagsusulat (dapat umiiral ang file);
  • "w+" - buksan ang isang walang laman na file para sa pagbabasa at pagsusulat; kung umiiral ang file, mawawala ang mga nilalaman nito;
  • "a+" - buksan ang file para sa pagbabasa at pagdaragdag kung ang file ay hindi umiiral, pagkatapos ito ay nilikha.

Ang return value ay isang pointer sa open stream. Kung ang isang error ay nakatagpo, NULL ay ibinalik.

Isinasara ng fclose() function ang stream o mga stream na nauugnay sa mga file na binuksan gamit ang fopen() function. Ang stream na isasara ay tinutukoy ng argumento ng fclose() function.

Return value: value 0 kung matagumpay na naisara ang stream; pare-pareho ang EOF kung may naganap na error.

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

#isama
int main() (
FILE *fp;
char name = "my.txt" ;
kung ((fp = fopen(pangalan, "r")) == NULL )
{
printf( "Nabigong buksan ang file");
getchar();
bumalik 0;
}
// nagtagumpay sa pagbukas ng file
... // mga kinakailangang aksyon sa data
fclose(fp);
getchar();
bumalik 0;
}

Pagbabasa ng isang character mula sa isang file:

char fgetc(stream);


Ang argument ng function ay isang pointer sa isang stream ng uri ng FILE. Ibinabalik ng function ang code ng read character. Kung ang dulo ng file ay naabot o naganap ang isang error, ang pare-parehong EOF ay ibabalik.

Pagsusulat ng isang simbolo sa isang file:

fputc(char, stream);

Ang mga argumento ng function ay isang character at isang pointer sa isang stream ng uri ng FILE. Ibinabalik ng function ang code ng read character.

Ang mga function ng fscanf() at fprintf() ay katulad ng scanf() at printf() function, ngunit gumagana sa mga data file, at mayroong file pointer bilang kanilang unang argumento.

fscanf(stream, "InputFormat", argumento);

– paghahambing upang matukoy ang pagkakapantay-pantay o hindi pagkakapantay-pantay.

Ang praktikal na layunin ng isang enumeration ay upang tukuyin ang isang hanay ng mga natatanging simbolikong constant ng isang uri ng integer.

Isang halimbawa ng paggamit ng mga enumerated variable:

mo=1, tu, kami, ika, fr, sa, su ) araw;

puts(“ Ipasok ang araw ng linggo (mula 1 hanggang 7) : ”); scanf(“%d”, &t_day);

w_day = su; simulan = mo;

katapusan = w_day -t_day;

printf(“\nAng Lunes ay ang %d araw ng linggo, \ngayon ang %d araw.\n\

Hanggang sa katapusan ng linggo %d araw (araw). ”, simula, t_day, end);

Resulta ng programa: Ipasok ang araw ng linggo (mula 1 hanggang 7): 2

Ang Lunes ay ang unang araw ng linggo, ngayon ay ang ika-2 araw. Mayroong 5 araw (araw) hanggang sa katapusan ng linggo.

18. Mga file sa wikang C

Ang file ay isang set ng data na matatagpuan sa external na media at isinasaalang-alang sa panahon ng pagproseso bilang isang solong kabuuan. Ang mga file ay naglalaman ng data na nilayon para sa pangmatagalang imbakan.

Mayroong dalawang uri ng mga file: text at binary. Ang mga text file ay isang pagkakasunud-sunod ng mga ASCII na character at maaaring tingnan at i-edit gamit ang anumang text editor.

Ang mga binary (binary) na file ay isang pagkakasunud-sunod ng data, ang istraktura nito ay tinutukoy ng software.

Ang wikang C ay may malaking hanay ng mga function para sa pagtatrabaho sa mga file, karamihan sa mga ito ay matatagpuan sa stdio.h at io.h na mga aklatan.

18.1. Pagbukas ng file

Ang bawat file ay itinalaga ng isang panloob na lohikal na pangalan, na ginagamit sa ibang pagkakataon kapag ina-access ito. Ang lohikal na pangalan (file identifier) ​​ay

pointer sa file, i.e. sa isang lugar ng memorya na naglalaman ng lahat ng kinakailangang impormasyon tungkol sa file. Ang format ng deklarasyon ng file pointer ay ang mga sumusunod:

FILE * pointer sa file;

FILE – pagkakakilanlan ng uri ng istraktura na inilarawan sa karaniwang aklatan

stdio.h at naglalaman ng sumusunod na impormasyon:

uri ng struct(

– ang bilang ng mga hindi pa nababasang byte na natitira sa buffer;

ang karaniwang laki ng buffer ay 512 bytes; sa sandaling antas=0,

ang susunod na bloke ng data ay binabasa sa buffer mula sa file;

– bandila ng katayuan ng file – basahin, isulat, idugtong;

– deskriptor ng file, ibig sabihin. bilang na tumutukoy sa hindi nito-

unsigned char hold;

– hindi nailipat na karakter, i.e. ungetc-character;

– laki ng panloob na intermediate buffer;

unsigned char buffer;

– halaga ng pointer para sa pag-access sa loob ng buffer, i.e.

tumutukoy sa simula ng buffer, sa simula ng linya, o sa kasalukuyang halaga

Ang halaga ng pointer sa loob ng buffer depende sa mode

ma buffering;

unsigned char *curp;

– kasalukuyang halaga ng pointer para sa pag-access sa loob ng

fera, ibig sabihin. tumutukoy sa kasalukuyang posisyon sa exchange buffer

sa programa;

unsigned istemp;

- pansamantalang bandila ng file;

– i-flag kapag nagtatrabaho sa isang file;

) FILE;

Bago ka magsimulang magtrabaho kasama ang file, i.e. Upang makapagbasa o makapagsulat ng impormasyon sa isang file, dapat itong buksan para ma-access. Para sa layuning ito ang function ay karaniwang ginagamit

FILE* fopen(char* file_name, char* mode);

nangangailangan ito ng panlabas na representasyon - ang pisikal na pangalan ng isang file sa isang medium (floppy disk, hard drive) at itinutugma ito sa isang lohikal na pangalan.

Pisikal na pangalan, i.e. ang pangalan ng file at landas dito ay tinukoy ng unang parameter

– isang linya, halimbawa, “a:Mas_dat.dat” – isang file na pinangalanang Mas_dat.dat na matatagpuan sa isang floppy disk, “d:\\work\\Sved.txt” – isang file na pinangalanang Sved.txt na matatagpuan sa hard magmaneho sa direktoryo ng trabaho.

Pansin! Ang backslash (\), bilang isang espesyal na karakter, ay nakasulat nang dalawang beses sa isang linya.

Sa matagumpay na pagbubukas, ang fopen function ay nagbabalik ng isang pointer sa file (mula dito ay tinutukoy bilang ang file pointer). Sa error, ibinalik ang NULL. Ang sitwasyong ito ay karaniwang nangyayari kapag ang landas sa file na bubuksan ay hindi tinukoy nang tama. Halimbawa, kung sa display class ng aming unibersidad ay tinukoy mo ang isang landas na ipinagbabawal para sa pagsusulat (karaniwan ay d:\work\ ang pinapayagan).

Ang pangalawang parameter ay isang linya na tumutukoy sa file access mode:

w - ang file ay binuksan para sa pagsusulat; kung walang file na may ibinigay na pangalan, ito ay malilikha; kung ang naturang file ay umiiral, pagkatapos ay ang nakaraang impormasyon ay nawasak bago buksan;

r – bubukas ang file para sa read only; kung walang ganoong file, nangyayari ang isang error;

a – ang file ay binuksan upang magdagdag ng bagong impormasyon sa dulo;

r+ - ang file ay binuksan para sa pag-edit ng data - parehong pagsusulat at pagbabasa ng impormasyon ay posible;

w+ – kapareho ng para sa r+;

a+ – katulad ng para sa a, tanging pagsusulat lang ang maaaring gawin kahit saan sa file; magagamit din ang pagbabasa ng file;

t – bubukas ang file sa text mode b – bubukas ang file sa binary mode.

Ang text mode ay naiiba sa binary mode dahil kapag ang isang file ay binuksan bilang isang pares ng text ng mga character na "line feed", ang "carriage return" ay pinalitan ng isang character: "line feed" para sa lahat ng mga function para sa pagsusulat ng data sa file, at para sa lahat ng output function ang character na “line feed” " ay pinapalitan na ngayon ng dalawang character: "line feed", "carriage return".

Bilang default, bubukas ang file sa text mode. Halimbawa: FILE *f; – ang isang pointer sa file f ay ipinahayag;

f = fopen("d:\\work\\Dat_sp.cpp", "w"); – isang file na may lohikal na pangalan f, na may pisikal na pangalan na Dat_sp.cpp, na matatagpuan sa drive d, sa direktoryo ng trabaho, ay binuksan para sa pagsulat; o mas maikli

FILE *f = fopen("d:\\work\\Dat_sp.cpp", "w");

18.2. Pagsasara ng file

Pagkatapos magtrabaho sa isang file, ang pag-access dito ay dapat na sarado. Ginagawa ito ng int fclose (file pointer) function. Halimbawa, mula sa nakaraang halimbawa ang file ay sarado tulad nito: fclose (f);

Upang isara ang maramihang mga file, isang function ay ipinakilala, ipinahayag tulad ng sumusunod: void fcloseall (walang bisa);

Kung kailangan mong baguhin ang access mode para sa isang file, kailangan mo munang isara ang file at pagkatapos ay buksan itong muli, ngunit may iba't ibang mga karapatan sa pag-access. Upang gawin ito, gamitin ang karaniwang function:

FILE* freopen (char*file_name, char *mode, FILE *file_pointer);

Isinasara muna ng function na ito ang file na ipinahayag file_pointer(tulad ng ginagawa ng fopen function), at pagkatapos ay bubuksan ang file na may file_name at mga pahintulot na "mode".

Ang wikang C ay may kakayahang magtrabaho kasama ang mga pansamantalang file na kailangan lamang habang tumatakbo ang programa. Sa kasong ito, ginagamit ang function

FILE* tmpfile (walang bisa);

na lumilikha ng isang pansamantalang file sa disk na may "w+b" na mga karapatan sa pag-access pagkatapos makumpleto ang programa o pagkatapos na isara ang pansamantalang file, awtomatiko itong tatanggalin.

18.3. Sumulat – basahin ang impormasyon

Ang lahat ng mga aksyon para sa pagbabasa at pagsulat ng data sa isang file ay maaaring nahahati sa tatlong grupo: character-by-character input-output operations; line-by-line na I/O operations; harangan ang mga operasyon ng I/O.

Tingnan natin ang mga pangunahing function na ginagamit sa bawat isa sa tatlong grupo ng mga operasyon na ito.

I/O ng character-by-character

Sa character-by-character na I/O function, isang character ang natatanggap mula sa isang file o isang character ang ipinadala sa isang file:

Row I/O

Linya I/O function transfer mula sa isang file o sa

I-block ang I/O

Ang mga function ng block I/O ay gumagana sa buong block

impormasyon:

int fread (void*p, insize,

– nagbabasa ng n bloke ng laki ng byte bawat isa mula sa file

int n, FILE *f)

la f sa isang lugar ng memorya na may pointer p (kinakailangan

int fwrite (void*p, insize,

maglaan ng memorya nang maaga para sa bloke na basahin);

– nagsusulat ng n bloke ng laki ng byte bawat isa mula sa

int n, FILE *f)

memory area na may pointer p sa file f.

Ang naka-format na I/O ay ginawa ng mga function.

Dati, kapag nag-input at nag-output ng data, nagtrabaho kami sa mga karaniwang stream - ang keyboard at monitor. Ngayon tingnan natin kung paano ipinapatupad ng wikang C ang pagtanggap ng data mula sa mga file at isinusulat ang mga ito doon. Bago mo maisagawa ang mga operasyong ito, dapat mong buksan ang file at i-access ito.

Sa C programming language, ang isang pointer sa isang file ay may uri ng FILE at ang deklarasyon nito ay ganito:
FILE *myfile;

Sa kabilang banda, ang fopen() function ay nagbubukas ng file sa address na tinukoy bilang unang argument sa read mode ("r"), write mode ("w"), o append mode ("a") at nagbabalik ng pointer dito sa programa. Samakatuwid, ang proseso ng pagbubukas ng isang file at pagkonekta nito sa programa ay mukhang ganito:
myfile = fopen("hello.txt", "r");

Kapag nagbabasa o nagsusulat ng data sa isang file, naa-access ito sa pamamagitan ng isang file pointer (sa kasong ito, myfile).

Kung sa isang kadahilanan o iba pa (walang file sa tinukoy na address, ang pag-access dito ay tinanggihan) ang fopen() function ay hindi maaaring mabuksan ang file, pagkatapos ay ibabalik nito ang NULL. Sa totoong mga programa, halos palaging pinangangasiwaan nila ang isang error sa pagbubukas ng file sa if branch, ngunit aalisin pa namin ito.

Ang deklarasyon ng function na fopen() ay nakapaloob sa stdio.h header file, kaya dapat itong isama. Gayundin sa stdio.h ang uri ng istraktura FILE ay ipinahayag.

Pagkatapos magtrabaho sa isang file ay tapos na, kaugalian na isara ito upang palayain ang buffer mula sa data at para sa iba pang mga kadahilanan. Ito ay lalong mahalaga kung ang programa ay patuloy na tatakbo pagkatapos magtrabaho kasama ang file. Ang pagsira sa koneksyon sa pagitan ng isang panlabas na file at isang pointer dito mula sa programa ay ginagawa gamit ang fclose() function. Ang isang pointer sa file ay ipinasa dito bilang isang parameter:
fclose(myfile);

Mahigit sa isang file ang maaaring mabuksan sa programa. Sa kasong ito, ang bawat file ay dapat na nauugnay sa sarili nitong file pointer. Gayunpaman, kung ang programa ay unang gumagana sa isang file at pagkatapos ay isasara ito, pagkatapos ay ang pointer ay maaaring gamitin upang magbukas ng pangalawang file.

Pagbasa mula at pagsulat sa isang text file

fscanf()

Ang function na fscanf() ay katulad ng kahulugan sa scanf() function, ngunit hindi katulad nito, nagbibigay ito ng naka-format na input mula sa isang file kaysa sa karaniwang input stream. Ang fscanf() function ay tumatagal ng mga parameter: file pointer, format string, mga address ng memory area para sa pagsusulat ng data:
fscanf(myfile, "%s%d", str, &a);

Ibinabalik ang bilang ng matagumpay na nabasang data o EOF. Ang mga puwang at bagong linya na mga character ay binibilang bilang mga delimiter ng data.

Sabihin nating mayroon tayong file na naglalaman ng sumusunod na paglalarawan ng mga bagay:

Mansanas 10 23.4 saging 5 25.0 tinapay 1 10.3

#isama pangunahing () ( FILE * file; struct food ( char name[ 20 ] ; unsigned qty; float price; ); struct food shop[ 10 ] ; char i= 0 ; file = fopen ( "fscanf.txt" , "r" ); while (fscanf (file, "%s%u%f" , shop[ i].name , & (shop[ i].qty ), & (shop[ i].price ) != EOF) ( printf ( "%s %u %.2f \n", tindahan[ i].pangalan, tindahan[ i].qty, tindahan[ i].presyo);

i++;

) )

Ang function na fgets() ay katulad ng gets() function at gumaganap ng line-by-line na input mula sa isang file. Ang isang tawag sa fgets() ay magbabasa ng isang linya. Sa kasong ito, hindi mo mababasa ang buong linya, ngunit bahagi lamang nito mula sa simula. Ang mga parameter ng fgets() ay ganito:
fgets (character_array, number_of_character_read, pointer_to_file)

Halimbawa:
fgets(str, 50, myfile)

Ang function call na ito ay magbabasa mula sa file na nauugnay sa myfile pointer ng isang buong linya ng text kung ang haba nito ay mas mababa sa 50 character, kasama ang "\n" character, na iimbak din ng function sa isang array. Ang huling (ika-50) elemento ng str array ay ang "\0" character na idinagdag ng fgets() . Kung mas mahaba ang string, magbabasa ang function ng 49 na character at magsusulat ng "\0" sa dulo. Sa kasong ito, hindi ilalagay ang "\n" sa nabasang linya.

#isama #define N 80 main () ( FILE * file; char arr[ N] ; file = fopen ("fscanf.txt" , "r" ); habang (fgets (arr, N, file) != NULL) printf (" %s" , arr); printf (" \n");

fclose(file);

)

Sa program na ito, hindi tulad ng nauna, ang data ay binabasa nang linya sa linya sa arr array. Kapag nabasa ang susunod na linya, nawala ang nauna. Ang function na fgets() ay nagbabalik ng NULL kung hindi nito mabasa ang susunod na linya.

getc() o fgetc() \n" Ang getc() o fgetc() function (parehong gumagana) ay nagpapahintulot sa iyo na makuha ang susunod na solong karakter mula sa isang file. \0 " habang ((arr[ i] = fgetc (file) ) != EOF) ( kung (arr[ i] == " \n") (arr[i] = " \0 " habang ((arr[ i] = fgetc (file) ) != EOF) ( kung (arr[ i] == " \n";

printf("%s

, arr);

i = 0 ;

  • ) iba i++;
  • )arr[i] = "
  • , arr);

Ang halimbawang code ay nagpapakita ng data mula sa isang file sa screen.

Pagsusulat sa isang text file

Tulad ng input, maaaring iba ang output sa isang file. \n" Naka-format na output. Function fprintf (file_index, format_string, variables) .

Post-by-line na output. Function fputs(string, file_pointer) .

Output ng character-by-character. Function fputc() o putc(simbolo, file_pointer) . \n" Nasa ibaba ang mga halimbawa ng code na gumagamit ng tatlong paraan ng pag-output ng data sa isang file.

Pagsusulat ng mga patlang ng isang istraktura sa bawat linya ng file:

habang ((i = getchar () ) != EOF) putc (i, file) ;

Pagbasa mula at pagsulat sa isang binary file

Maaari kang magtrabaho sa isang file hindi bilang isang pagkakasunud-sunod ng mga character, ngunit bilang isang pagkakasunud-sunod ng mga byte. Sa prinsipyo, hindi posible na gumana sa mga non-text na file sa anumang iba pang paraan. Gayunpaman, maaari rin itong gamitin upang magbasa at magsulat sa mga text file. Ang bentahe ng pamamaraang ito ng pag-access sa isang file ay ang bilis ng read-write: ang isang makabuluhang bloke ng impormasyon ay maaaring basahin/isulat sa isang pag-access.

Kapag nagbubukas ng file para sa binary access, ang pangalawang parameter sa fopen() ay ang string na "rb" o "wb".

Ang paksa ng pagtatrabaho sa mga binary file ay medyo kumplikado at nangangailangan ng isang hiwalay na aralin upang pag-aralan ito. Dito lamang mapapansin ang mga tampok ng mga function ng pagbabasa at pagsulat sa isang file, na itinuturing bilang isang byte stream.

Ang mga function ng fread() at fwrite() ay kinukuha bilang mga parameter:

  1. address ng lugar ng memorya kung saan nakasulat o nabasa ang data,
  2. ang laki ng isang ibinigay na anumang uri,
  3. ang dami ng data na nabasa ng tinukoy na laki,
  4. index ng file.

Ibinabalik ng mga function na ito ang bilang ng data na matagumpay na nabasa o naisulat. Yung. maaari mong "i-order" ang pagbabasa ng 50 elemento ng data, ngunit makatanggap lamang ng 10. Walang magiging error.

Isang halimbawa ng paggamit ng mga function ng fread() at fwrite():

#isama #isama pangunahing () ( FILE * file; char shelf1[ 50 ], shelf2[ 100 ] ; int n, m; file = fopen ("shelf1.txt" , "rb" ); n= fread (shelf1, sizeof (char ), 50 , file); fclose (file) ; file = fopen ("shelf2.txt" , "rb" ); \0 " ; \n" istante2[m] = " \0 " ;

istante2[ m+ 1 ] = "

;

  1. file = fopen ("shop.txt" , "wb" );
  2. fwrite (strcat (shelf2, shelf1), sizeof (char ), n+ m, file);

fclose(file);

) FileStream kumakatawan sa mga kakayahan ng pagbabasa mula sa isang file at pagsulat sa isang file. Pinapayagan ka nitong magtrabaho kasama ang parehong mga text file at mga binary.

Isaalang-alang natin ang pinakamahalagang katangian at pamamaraan nito:

    Length property: ibinabalik ang haba ng stream sa bytes

    Position property: ibinabalik ang kasalukuyang posisyon sa stream

    Paraan ng pagbabasa: Nagbabasa ng data mula sa isang file patungo sa isang byte array. Kumukuha ng tatlong parameter: int Read(byte array, int offset, int count) at ibinabalik ang bilang ng mga byte na matagumpay na nabasa. Ang mga sumusunod na parameter ay ginagamit dito:

    • array - isang hanay ng mga byte kung saan ilalagay ang data na nabasa mula sa file

      kinakatawan ng offset ang offset sa mga byte sa array kung saan ilalagay ang mga read byte

      count - ang maximum na bilang ng mga byte na babasahin. Kung may mas kaunting mga byte sa file, lahat ng mga ito ay mababasa.

    Pamamaraan long Seek(long offset, SeekOrigin origin): nagtatakda ng posisyon sa stream na may offset ng bilang ng mga byte na tinukoy sa offset parameter.

    Paraan ng pagsulat: Sumulat ng data mula sa isang byte array patungo sa isang file. Tumatagal ng tatlong parameter: Sumulat (byte array, int offset, int count)

    • array - isang hanay ng mga byte kung saan isusulat ang data sa file

      offset - ang offset sa bytes sa array mula sa kung saan ang mga byte ay nagsisimulang isulat sa stream

      count - maximum na bilang ng mga byte na isusulat

Kinakatawan ng FileStream ang pag-access ng file sa antas ng byte, kaya, halimbawa, kung kailangan mong magbasa o magsulat ng isa o higit pang mga linya sa isang text file, dapat na i-convert ang byte array sa mga string gamit ang mga espesyal na pamamaraan. Samakatuwid, ang ibang mga klase ay ginagamit upang gumana sa mga text file.

Kasabay nito, kapag nagtatrabaho sa iba't ibang mga binary file na may isang tiyak na istraktura, ang FileStream ay maaaring maging lubhang kapaki-pakinabang para sa pagkuha ng ilang piraso ng impormasyon at pagproseso nito.

Tingnan natin ang isang halimbawa ng pagbabasa at pagsulat sa isang text file:

Console.WriteLine("Magpasok ng linyang isusulat sa file:"); string text = Console.ReadLine(); // pagsulat sa isang file gamit ang (FileStream fstream = bagong FileStream(@"C:\SomeDir\noname\note.txt", FileMode.OpenOrCreate)) ( // convert ang string sa bytes byte array = System.Text.Encoding. Default. GetBytes(text); // pagsulat ng array ng mga byte sa isang file fstream.Write(array, 0, array.Length); fstream = File. OpenRead(@"C:\SomeDir\noname\note.txt")) ( // convert ang string sa byte byte array = new byte; // basahin ang data fstream.Read(array, 0, array. Haba); // decode bytes to string string textFromFile = System.Text.Encoding.Default.GetString(array.WriteLine("Text from file: (0)", textFromFile ) Console.ReadLine();

Tingnan natin ang halimbawang ito. Parehong ginagamit ang pagbabasa at pagsulat ng gamit na pahayag. Ang pahayag na ito ay hindi dapat malito sa paggamit ng direktiba, na kinabibilangan ng mga namespace sa simula ng code file. Ang gamit na pahayag ay nagbibigay-daan sa iyo na lumikha ng isang bagay sa isang bloke ng code, sa pagkumpleto kung saan ang Dispose method ng bagay na iyon ay tinatawag, at sa gayon ang bagay ay nawasak. Sa kasong ito, ang variable ng fstream ay nagsisilbing isang bagay.

Ang bagay na fstream ay nilikha sa dalawang magkaibang paraan: sa pamamagitan ng constructor at sa pamamagitan ng isa sa mga static na pamamaraan ng klase ng File.

Dito, dalawang parameter ang ipinapasa sa constructor: ang file path at ang FileMode enumeration. Isinasaad ng enumeration na ito ang file access mode at maaaring kunin ang mga sumusunod na value:

    Idagdag: kung umiiral ang file, idaragdag ang teksto sa dulo ng file. Kung ang file ay hindi umiiral, ito ay nilikha. Ang file ay binuksan para sa pagsulat lamang.

    Lumikha: Isang bagong file ang nilikha. Kung mayroon nang ganoong file, ito ay mapapatungan

    CreateNew: Isang bagong file ang ginawa. Kung mayroon nang ganoong file, ang application ay magtapon ng isang error

    Buksan: Nagbubukas ng file. Kung ang file ay hindi umiiral, ang isang pagbubukod ay itinapon

    OpenOrCreate : kung umiiral ang file, bubuksan ito, kung hindi, gagawa ng bago

    Putulin: Kung ang file ay umiiral, ito ay mapapatungan. Ang file ay binuksan para sa pagsulat lamang.

Ang static na OpenRead na paraan ng klase ng File ay nagbubukas ng file para sa pagbabasa at nagbabalik ng isang FileStream object.

Ang FileStream class constructor ay mayroon ding ilang mga overload na nagbibigay-daan sa iyong mas tumpak na i-customize ang object na ginagawa. Ang lahat ng mga bersyon na ito ay maaaring matingnan sa msdn.

Parehong ginagamit ang pagsusulat at pagbabasa ng Encoding.Default na encoding object mula sa System.Text namespace. Sa kasong ito, ginagamit namin ang dalawa sa mga pamamaraan nito: GetBytes upang makakuha ng isang byte array mula sa isang string at GetString upang makakuha ng isang string mula sa isang byte array.

Bilang resulta, ang string na ipinasok namin ay nakasulat sa file note.txt. Sa esensya, ito ay isang binary file (hindi isang text file), bagama't kung magsusulat lamang tayo ng isang linya dito, maaari nating tingnan ang file na ito sa isang form na nababasa ng tao sa pamamagitan ng pagbubukas nito sa isang text editor. Gayunpaman, kung sumulat kami ng mga random na byte dito, halimbawa:

Fstream.WriteByte(13); fstream.WriteByte(103);

Pagkatapos ay maaaring magkaroon tayo ng mga problema sa pag-unawa dito. Samakatuwid, ang mga hiwalay na klase ay idinisenyo upang gumana nang direkta sa mga text file - StreamReader at StreamWriter.

Random na pag-access sa mga file

Kadalasan ang mga binary file ay kumakatawan sa isang partikular na istraktura. At, alam ang istrakturang ito, maaari naming kunin ang kinakailangang piraso ng impormasyon mula sa file o, sa kabaligtaran, magsulat ng isang tiyak na hanay ng mga byte sa isang tiyak na lugar sa file. Halimbawa, sa mga wav file, ang audio data mismo ay nagsisimula sa 44 bytes, at hanggang 44 bytes ay mayroong iba't ibang metadata - ang bilang ng mga audio channel, sampling frequency, atbp.

Gamit ang pamamaraang Seek(), makokontrol natin ang posisyon ng stream cursor, simula sa kung saan isinasagawa ang pagbabasa o pagsusulat sa file. Ang pamamaraang ito ay tumatagal ng dalawang parameter: offset at posisyon sa file. Ang isang posisyon sa isang file ay inilalarawan ng tatlong halaga:

    SeekOrigin.Begin : simula ng file

    SeekOrigin.End : dulo ng file

    SeekOrigin.Current : kasalukuyang posisyon sa file

Ang cursor ng stream kung saan nagsisimula ang pagbabasa o pagsusulat ay inilipat pasulong sa pamamagitan ng offset na nauugnay sa posisyong tinukoy bilang pangalawang parameter. Maaaring negatibo ang offset, pagkatapos ay gumagalaw ang cursor pabalik, kung positibo, pagkatapos ay pasulong.

Tingnan natin ang isang halimbawa:

Gamit ang System.IO; gamit ang System.Text; class Program ( static void Main(string args) ( string text = "hello world"; // pagsulat sa isang file gamit ang (FileStream fstream = bagong FileStream(@"D:\note.dat", FileMode.OpenOrCreate)) ( / / convert ang string sa bytes input = Encoding.Default.GetBytes(text); // magsulat ng array ng mga byte sa isang file fstream.Write(input, 0, input.Length); ); ilipat ang pointer sa dulo ng file, limang byte sa dulo ng file fstream.Seek(-5, SeekOrigin.End); kasalukuyang posisyon byte output = bagong byte( output, 0, output.Length); // decode ang mga byte sa isang string string textFromFile = Encoding.Default.GetString(output); , textFromFile); sa file ang word na mundo sa salitang house string replaceText = "house"; GetBytes(replaceText , 0, input.Length);

// basahin ang buong file // ibalik ang pointer sa simula ng file fstream.Seek(0, SeekOrigin.Begin);

output = bagong byte;

fstream.Read(output, 0, output.Length);

// decode ang mga byte sa isang string textFromFile = Encoding.Default.GetString(output);

Console.WriteLine("Text mula sa file: (0)", textFromFile); // hello house ) Console.Read();

) )

Output ng console:

Text na nakasulat sa file Text mula sa file: worl Text mula sa file: hello house

FileStream fstream = null; subukan ( fstream = bagong FileStream(@"D:\note3.dat", FileMode.OpenOrCreate); // mga operasyon na may stream ) catch(Exception ex) ( ) sa wakas ( kung (fstream != null) fstream.Close() ;)

Kung hindi kami gagamit ng gamit na construct, kailangan naming tahasang tawagan ang Close() method: fstream.Close()

Ang fopen() function ay nagbubukas ng stream para magamit, nag-uugnay ng file sa stream na iyon, at pagkatapos ay nagbabalik ng FILE pointer sa stream na iyon. Kadalasan ang file ay itinuturing bilang isang disk file. Ang fopen() function ay may sumusunod na prototype:

FILE *fopen(const char *filename, const char *mode);

Kung saan ang mode ay tumuturo sa isang string na naglalaman ng nais na mode para sa pagbubukas ng file. Ang mga wastong halaga para sa mode sa Borland C++ ay ipinapakita sa talahanayan. Ang filename ay dapat na isang string ng character na nagbibigay ng wastong filename sa operating system, at maaaring naglalaman ng pathname.

Ang fopen() function ay nagbabalik ng pointer sa base type na FILE. Tinutukoy ng pointer na ito ang file at ginagamit ng karamihan sa mga function ng file system. Hindi mo dapat baguhin ito sa iyong sarili. Ang function ay nagbabalik ng isang null pointer kung ang file ay hindi mabubuksan.

Tulad ng ipinapakita ng talahanayan, mabubuksan ang file sa alinman sa text o binary mode. Sa text mode, habang nagta-type ka, ang sequence ng carriage return at line feed ay isinasalin sa isang newline na character. Sa output, ang kabaligtaran ay totoo: ang newline na character ay isinalin sa isang carriage return at isang line feed. Ang pagsasaling ito ay hindi nangyayari sa mga binary file. Kapag hindi tinukoy ang t o b sa argument ng mode, ang text/binary status ng file ay tinutukoy ng halaga ng global variable na _fmode na tinukoy sa Borland C++. Bilang default, nakatakda ang fmode sa O_TEXT, ibig sabihin, nakatakda ang text mode. Kung itinakda mo ang _fmode sa O_BINARY, mabubuksan ang mga file sa binary mode. (Ang mga macro na ito ay tinukoy sa fcntl.h.) Natural, ang paggamit ng tahasang t o b ay nag-aalis ng mga epekto na nauugnay sa variable na _fmode. Bilang karagdagan, ang _fmode ay partikular sa mga produkto ng Borland lamang. Hindi ito tinukoy sa ANSI C I/O system.

Kung kailangan mong magbukas ng file na pinangalanang pagsubok para sa pagsulat, dapat mong isulat ang:

Fp = fopen("test", "w");

Kung saan ang fp ay isang variable ng uri ng FILE *. Gayunpaman, karaniwan na makita ang mga sumusunod:

If((fp = fopen("test", "w"))==NULL) (
puts("Hindi mabuksan ang file.");
exit(1);
}

Ang pamamaraang ito ay nagbibigay-daan sa iyo upang makita ang mga error kapag binubuksan ang isang file, halimbawa, ang pagkakaroon ng proteksyon sa pagsulat o kakulangan ng libreng espasyo sa disk.

Kung ang fopen() ay ginagamit upang buksan ang isang file para sa pagsusulat, ang anumang dati nang file na may tinukoy na pangalan ay tatanggalin. Kung ang isang file na may tinukoy na pangalan ay hindi umiiral, ito ay malilikha.

Kung kailangan mong magdagdag ng impormasyon sa dulo ng file, dapat mong gamitin ang mode a (idagdag). Kung ang file ay hindi umiiral, ito ay malilikha.

Ang pagbubukas ng isang file para sa pagbabasa ay nangangailangan ng pagkakaroon ng file. Kung wala ang file, may ibabalik na error. Kung ang isang file ay binuksan para sa read/write operation, pagkatapos ay hindi ito tatanggalin kung ito ay umiiral, at kung ang file ay hindi umiiral, pagkatapos ito ay nilikha.

Talahanayan: Mga halaga ng pinapayagang mode

Ibig sabihin

Nagbubukas ng file para sa pagbabasa. (Nagbubukas bilang default bilang isang text file.)

Gumagawa ng file na pagsusulatan. (Nagbubukas bilang default bilang isang text file.)

Nakakabit sa isang file. (Nagbubukas bilang default bilang isang text file.)

Nagbubukas ng binary file para sa pagbabasa.

Nagbubukas ng binary file para sa pagsusulat.

Nakakabit sa isang binary file.

Nagbubukas ng file para sa pagbabasa/pagsusulat. (Nagbubukas bilang default bilang isang text file.)

Lumilikha ng read/write file. (Nagbubukas bilang default bilang isang text file.)

Nag-attach o gumagawa ng read/write file. (Nagbubukas bilang default bilang isang text file.)

Nagbubukas ng binary file para sa pagbabasa/pagsusulat.

Lumilikha ng read/write binary file.

Nag-a-attach o gumagawa ng read/write binary file.

Lumilikha ng isang text file para sa pagsusulat.

Nakakabit sa isang text file.

Nagbubukas ng text file para sa pagbabasa.

Lumilikha ng isang text file para sa pagbabasa/pagsusulat.

Nagbubukas o gumagawa ng text file para sa pagbabasa/pagsusulat.