Ункцґ» длЯ роботи з файлами

ВеденнЯ/виведеннЯ файлґв

™об працювати з файлом, його спочатку слґд вґдкрити: зв'Язати зґ спецґальною структурою з ґм'Ям FILE, Яка описана в бґблґотецґ stdio.h ґ в Якґй задаютьсЯ характеристики файлу (розмґр буфера введеннЯ/виведеннЯ, стан файлу, останнґй прочитаний запис ґ т.п.). ‡в'Язок цей викону№тьсЯ за допомогою функцґ» fopen (), Яка теж входить в бґблґотеку stdio.h ґ поверта№ вказґвник на структуру FILE. ’ому в програмґ, перш за все, слґд задати вказґвник на структуру FILE, а потґм записати оператор вґдкриттЯ файлу:

FILE *fp;

fp = fopen(<ґмХЯ_файлу>, <спосґб_вґдкриттЯ_файлу>);

”ункцґЯ fopen () ма№ два параметри: ґм'Я файлу ґ спосґб вґдкриттЯ файлу. ‘посґб вґдкриттЯ файлу визнача№, Як користувач буде працювати з файлом: читати його, писати в нього данґ або робити щось ще.

‘пособи вґдкриттЯ файлу ґ »х коди можуть бути наступнґ:

- r - файл вґдкрива№тьсЯ тґльки длЯ читаннЯ даних з нього;

- w - файл вґдкрива№тьсЯ тґльки длЯ запису в нього (Якщо файл не ґсну№, вґн створю№тьсЯ автоматично ґ вґдкрива№тьсЯ длЯ запису);

- a - файл вґдкрива№тьсЯ длЯ дозапису даних у кґнець файлу (Якщо файл не ґсну№, вґн створю№тьсЯ длЯ запису);

- r+ - ґснуючий файл вґдкрива№тьсЯ длЯ поновленнЯ: можна ґ читати з файлу, ґ записувати в нього данґ;

- w+ - створю№тьсЯ новий файл длЯ поновленнЯ: можна ґ читати, ґ записувати в нього данґ;

- a+ - файл вґдкрива№тьсЯ длЯ дозапису даних у кґнець файлу (Якщо файл не ґсну№, вґн створю№тьсЯ автоматично ґ вґдкрива№тьсЯ длЯ запису).

џкщо з Яко»сь причини вґдкриттЯ файлу не вґдбулосЯ (наприклад, в режимґ r+ задано ґм'Я неґснуючого файлу), то функцґЯ fopen () поверта№ значеннЯ NULL. ’ому при вґдкриттґ файлу слґд здґйснювати перевґрку:

If ((fp = fopen((<ґмХЯ_файлу>, <спосґб_вґдкриттЯ_файлу>) == NULL) { оператори обробки помилки вґдкриттЯ} { ґншґ оператори програми }

ЏґслЯ того, Як програма з даним файлом вґдпрацювала, слґд "вґдв'Язати" структуру FILE вґд файлу або, Як кажуть, закрити файл. –е здґйсню№ функцґЯ fclose (fp). ‚она не тґльки розрива№ зв'Язок структури з файлом, але ґ запису№ в пам'Ять залишившийсЯ вмґст буфера введеннЯ/виведеннЯ, через Який ґ органґзу№тьсЯ введеннЯ/виведеннЯ. ’ґльки пґслЯ закриттЯ файлу з ним можна виконувати Якґ-небудь дґ», тому що вґн "вґльний", "не прив'Язаний". Ќаприклад, його можна видалити або знову вґдкрити в ґншому режимґ вґдкриттЯ ґ т. д.

ункцґ» длЯ роботи з файлами

ЏґслЯ того, Як файл вґдкритий, то длЯ читаннЯ або запису даних використовують спецґальнґ функцґ». Ќаведемо перелґк функцґй длЯ роботи з файлами.

”ункцґЯ fputc()

”ормат функцґ»:

fputc(<символ,_що_виводитьсЯ_у_файл>, вказґвник_на_файл);

”ункцґЯ виводить символ в файл: вказґвник_на_файл, наприклад fp.

/* KTOD: програма по символьного введеннЯ з клавґатури та посимвольного виведеннЯ на диск. */

# include <stdlib.h>

# include <stdio.h>

# include <windows.h>

# include <locale.h>

 

int main() {

setlocale(LC_CTYPE, "Russian");

FILE *fp;

char ch;

if((fp=fopen("test", "w"))==NULL) {

printf("Џомилка при вiдкриттi файлу.\n");

system ("pause");

exit(1);

}

printf("‚ведiть рЯдок символiв. Ћзнакою кiнцЯ операцii перемiщеннЯ символiв у файл буде символ $ ґ [Enter] \n");

do {

ch = getchar();

fputc(ch, fp);

} while (ch != '$');

fclose(fp);

system ("pause");

return 0;

}

 

”ункциЯ fgetc()

”ормат функцґ»:

char c = fgetc(fp);

—ита№ один символ з файлу з вказґвником fp. “ випадку помилки або досЯгненнЯ кґнцЯ файлу поверта№ EOF.

/* DTOS: програма, Яка чита№ посимвольно файл ґ виводить його вмґст на екран. */

# include <stdlib.h>

# include <stdio.h>

# include <windows.h>

# include <locale.h>

 

int main() {

setlocale(LC_CTYPE, "Russian");

FILE *fp;

char ch;

if((fp=fopen("test", "r"))==NULL) {

printf("Џомилка при вiдкриттi файлу.\n");

system ("pause");

exit(1);

}

printf("‡читаний з файлу рЯдок \n");

ch = fgetc (fp); /* читаннЯ одного символу */

while (ch != EOF) {

putchar (ch); /* виведеннЯ на екран */

ch = fgetc (fp);

}

printf("\n");

fclose(fp);

system ("pause");

return 0;

}

 

”ункциЯ feof()

”ормат функцґ»:

feof(fp);

џк вже говорилосЯ, Якщо досЯгнуто кґнець файлу, то fgetc () поверта№ EOF. Ћднак перевґрка значеннЯ, повернутого fgetc (), можливо, не № найкращим способом дґзнатисЯ, чи досЯгнутий кґнець файлу. Џо-перше, файлова система мови ‘ може працювати Як з текстовими, так ґ з двґйковими файлами. Љоли файл вґдкрива№тьсЯ длЯ двґйкового введеннЯ, то може бути прочитане цґле значеннЯ, Яке, Як з'Ясу№тьсЯ при перевґрцґ, дорґвню№ EOF. “ такому випадку програма введеннЯ повґдомить про те, що досЯгнуто кґнець файлу, чого насправдґ може ґ не бути. Џо-друге, функцґЯ fgetc () поверта№ EOF ґ в разґ вґдмови, а не тґльки тодґ, коли досЯгнуто кґнець файлу. џкщо використовувати тґльки повернене значеннЯ fgetc (), то неможливо визначити, що ж насправдґ сталосЯ. „лЯ вирґшеннЯ цґ№» проблеми в ‘ № функцґЯ feof (), Яка визнача№, чи досЯгнутий кґнець файлу. Џрототип функцґ» feof () такий:

int feof(FILE <вказґвник файлу>);

џкщо досЯгнуто кґнець файлу, то feof () поверта№ true (ґстина), в ґншому ж випадку цЯ функцґЯ поверта№ хибнґсть. ’ому наступний код буде читати двґйковий файл до тих пґр, поки не буде досЯгнутий кґнець файлу:

while(!feof(<вказґвник файлу>)) ch = fgetc(<вказґвник файлу>);

џсно, що цей метод можна застосовувати Як до двґйковим, так ґ до текстових файлґв.

“ наступнґй програмґ, Яка копґю№ текстовґ або двґйковґ файли, наведено приклад застосуваннЯ feof (). ”айли вґдкриваютьсЯ в двґйковому режимґ, а потґм feof () перевґрЯ№, чи не досЯгнуть кґнець файлу.

/* ЉопґюваннЯ файлу. */

# include <stdlib.h>

# include <stdio.h>

# include <windows.h>

# include <locale.h>

 

int main() {

setlocale(LC_CTYPE, "Russian");

FILE *in, *out;

char ch;

if((in=fopen("testr", "rb"))==NULL) {

printf("Ќе можна вiдкрити вхiдний файл.\n");

system ("pause");

exit(1);

}

if((out=fopen("testw", "wb"))==NULL) {

printf("Ќе можна вiдкрити файл результатiв.\n");

system ("pause");

exit(1);

}

/* ‘аме цей код копґю№ файл. */

while (! feof (in)) {

ch = getc (in);

if (!feof (in)) fputc (ch, out);

}

fclose (in);

fclose (out);

system ("pause");

return 0;

}

 

‚иЯвлЯ№ кґнець файлу з вказґвником fp: тесту№ потґк на виникненнЯ ґндикатора кґнцЯ файлу (Який наста№ пґслЯ прочитаннЯ останнього запису). џк тґльки ґндикатор встановлений, операцґ» читаннЯ файлу повертають ґндикатор до тих пґр, поки не виконана функцґЯ rewind () - "перемотуваннЯ" в початок файлу, або поки файл не буде закритий. §ндикатор кґнцЯ файлу перевстановлю№тьсЯ з кожною операцґ№ю введеннЯ. ”ункцґЯ поверта№ ненульову величину, Якщо ґндикатор кґнцЯ файлу був виЯвлений при останнґй операцґ» читаннЯ, в ґншому випадку - нуль.

”ункцґЯ fputs()

”ормат функцґ»:

fputs(<виведений рЯдок >, <вказґвник_на_файл>);

”ункцґЯ виводить рЯдок у файл.

#include <stdlib.h>

#include <stdio.h>

#include <windows.h>

#include <locale.h>

#include <string.h>

 

int main() {

setlocale(LC_CTYPE, "Russian");

char str [80];

FILE *fp;

if ((fp = fopen ("TEST", "w")) == NULL) {

printf ("Џомилка при вiдкриттi файлу. \ n");

system ("pause");

exit(1);

}

do {

printf ("‚ведiть рЯдок (порожнiй рЯдок - длЯ виходу): \n");

gets (str);

strcat (str, "\n"); // додаваннЯ роздґльника рЯдкґв

fputs (str, fp);

} while (strcmp("\n", str)); // strcmp() - порґвнЯннЯ рЯдкґв

fclose (fp);

system ("pause");

return 0;

 

”ункциЯ fgets()

”ормат функцґ»:

fgets(s, maxline, fp);

—ита№ рЯдок в s, де s - масив символґв або вказґвник типу char (попередньо повинна бути видґлена пам'Ять длЯ читаннЯ з використаннЯм вказґвника), maxline - максимальне число символґв, Яке потрґбно читати з файлу з вказґвником fp. “ випадку помилки або досЯгненнЯ кґнцЯ файлу поверта№ NULL.

”ункцґЯ fgets () чита№ з певного потоку рЯдок, ґ робить це до тих пґр, поки не буде прочитаний символ нового рЯдка або кґлькґсть прочитаних символґв не стане рґвним maxline. џкщо був прочитаний роздґльник рЯдкґв, вґн заноситьсЯ в рЯдок.

 

# include <stdlib.h>

# include <stdio.h>

# include <windows.h>

# include <locale.h>

# include <string.h>

 

int main() {

setlocale(LC_CTYPE, "Russian");

char str [80];

int i=0;

FILE *fp;

if ((fp = fopen ("test", "r")) == NULL) {

printf ("Џомилка при вiдкриттi файлу. \n");

system ("pause");

exit(1);

}

while (! feof (fp)) {

i++;

printf ("Ѓуде прочитано i виведено %d-й рЯдок ", i);

fgets (str, 79, fp);

printf (str);

}

printf ("\n");

fclose (fp);

system ("pause");

return 0;

}

 

”ункциЯ fread()

”ормат функцґ»:

fread(buf, m, n, fp);

–Я функцґЯ чита№ з файлу з вказґвником fp першґ n елементґв даних, кожен з Яких ма№ довжину m байт. —итаннЯ вґдбува№тьсЯ в буфер, на Який вказу№ вказґвник buf, наприклад, char buf [50] або char * buf (але в останньому випадку попередньо треба видґлити пам'Ять длЯ буфера). ‡агальна кґлькґсть байт читаннЯ складе (n * m). ”ункцґЯ поверта№ кґлькґсть прочитаних елементґв, а по досЯгненнґ кґнцЯ файлу або виникненнґ помилки читаннЯ поверта№ NULL.

”ункциЯ fwrite()

”ормат функцґ»:

fwrite(ptr, m, n, fp);

”ункцґЯ дода№ n елементґв у файл з вказґвником fp, кожен елемент довжиною в m байт. „анґ записуютьсЯ з буфера, на Який вказу№ вказґвник ptr (цей вказґвник вказу№ на деЯкий об'№кт, наприклад, на структуру). ‡агальна кґлькґсть записаних байтґв дорґвню№ (n * m). “ випадку помилки запису функцґЯ поверта№ нуль, в ґншому випадку - кґлькґсть записаних елементґв.

џк тґльки файл вґдкритий длЯ роботи з двґйковими даними, fread () ґ fwrite () вґдповґдно можуть читати ґ записувати ґнформацґю будь-Якого типу. Ќаприклад, наступна програма запису№ в дисковий файл данґ типґв double, int ґ long, a потґм чита№ цґ данґ з того ж файлу. ‡вернґть увагу, Як в цґй програмґ при визначеннґ довжини кожного типу даних використову№тьсЯ функцґЯ sizeof ().

/* ‡апис несґмвольних даних в дисковий файл

ґ подальше »х читаннЯ. */

# include <stdlib.h>

# include <stdio.h>

# include <windows.h>

# include <locale.h>

# include <ctype.h>

 

int main() {

setlocale(LC_CTYPE, "Russian");

FILE * fp;

float d = 12.23;

int i = 101;

long l = 123023L;

if ((fp = fopen ("test", "wb+")) == NULL) {

printf ("Џомилка при вґдкриттґ файлу. \n");

system ("pause");

exit (1);

}

fwrite (&d, sizeof (double), 1, fp);

fwrite (&i, sizeof (int), 1, fp);

fwrite (&l, sizeof (long), 1, fp);

rewind (fp);

fread (&d, sizeof (double), 1, fp);

fread (&i, sizeof (int), 1, fp);

fread (&l, sizeof (long), 1, fp);

printf ("%4.2f %d %ld", d, i, l);

printf ("\n");

fclose (fp);

system ("pause");

return 0;

}

џк видно з цґ№» програми, в Якостґ буфера можна використовувати (ґ часто саме так ґ роблЯть) просто пам'Ять, в Якґй розмґщена змґнна. “ цґй простґй програмґ значеннЯ, що повертаютьсЯ функцґЯми fread () ґ fwrite (), ґгноруютьсЯ. Ћднак на практицґ цґ значеннЯ необхґдно перевґрЯти, щоб виЯвити помилки.

Ћдним з найбґльш корисних застосувань функцґй fread () ґ fwrite () № читаннЯ ґ запис даних користувача типґв, особливо структур. Ќаприклад, Якщо визначена структура

struct struct_type {

float balance;

char name [80];

} Cust;

то наступний оператор запису№ вмґст cust в файл, на Який вказу№ fp:

fwrite (& cust, sizeof (struct struct_type), 1, fp);