Ункцґ» длЯ роботи з файлами
ВеденнЯ/виведеннЯ файлґв
™об працювати з файлом, його спочатку слґд вґдкрити: зв'Язати зґ спецґальною структурою з ґм'Ям 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);