Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Риклад зґ списком роззсилки




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

struct addr {

char name [30];

char street [40];

char city [20];

char state [3];

unsigned long int zip;

} Addr_list [MAX];

‡наченнЯ MAX визнача№ максимальну кґлькґсть адрес, що може бути у списку.

Џри виконаннґ програми поле name кожно» структури ґнґцґалґзу№тьсЯ порожнґм вказґвником (NULL). “ програмґ вґльною вважа№тьсЯ та структура, поле name Яко» мґстить рЯдок нульово» довжини, тобто ґм'Я адресата ЯвлЯ№ собою порожнґм рЯдком.

„алґ наведенґ функцґ» save () ґ load (), Якґ використовуютьсЯ вґдповґдно длЯ збереженнЯ ґ завантаженнЯ бази даних (списку розсилки). ‡вернґть увагу, наскґльки коротко вдалосЯ закодувати кожну з функцґй, а адже цЯ стислґсть досЯгнута завдЯки потужностґ fread () ґ fwrite ()! § ше звернґть увагу на те, Як цґ функцґ» перевґрЯють значеннЯ, що повертаютьсЯ функцґЯми fread () ґ fwrite (), щоб виЯвити таким чином можливґ помилки.

/* ‡береженнЯ списку. */

void save (void) {

FILE *fp;

register int i;

if ((fp = fopen ("maillist", "wb")) == NULL) {

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

return;

}

for (i = 0; i <MAX; i++)

if (*addr_list[i].name)

if (fwrite (&addr_list[i], sizeof (struct addr), 1, fp)!= 1)

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

fclose (fp);

}

/* ‡авантажити файл. */

void load (void) {

FILE *fp;

register int i;

if ((fp = fopen ("maillist", "rb")) == NULL) {

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

return;

}

init_list ();

for (i = 0; i <MAX; i++)

if (fread (&addr_list[i], sizeof (struct addr), 1, fp)!= 1) {

if (feof (fp)) break;

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

}

fclose (fp);

}

Ћбидвґ функцґ», save () ґ load (), пґдтверджують (або не пґдтверджують) успґшнґсть виконаннЯ функцґЯми fread () ґ fwrite () операцґй з файлом, перевґрЯючи значеннЯ, що повертаютьсЯ функцґЯми fread () ґ fwrite (). Љрґм того, функцґЯ load () Явно перевґрЯ№, чи не досЯгнуто кґнець файлу. ђобить вона це за допомогою виклику функцґ» feof (). –е доводитьсЯ робити тому, що fread () ґ в разґ помилки, ґ при досЯгненнґ кґнцЯ файлу поверта№ одне ґ те ж значеннЯ.

„алґ показана всЯ програма, що оброблЯ№ списки розсилки. є» можна використовувати Як Ядро длЯ подальших розширень, в не», наприклад, можна додати засоби пошуку адрес.

/* Џроста програма обробки списку розсилки,

в Якґй використову№тьсЯ масив структур. */

# include <windows.h>

# include <locale.h>

# include <stdio.h>

# include <stdlib.h>

# define MAX 100

 

struct addr {

char name [30];

char street [40];

char city [20];

char state [20];

unsigned long int zip;

} addr_list [MAX];

void init_list (), enter ();

void delete1 (), list ();

void load (), save ();

int menu_select (), find_free ();

 

int main() {

setlocale(LC_CTYPE, "Russian");

char choice;

init_list (); /* ґнґцґалґзацґЯ масиву структур */

for (;;) {

choice = menu_select ();

switch (choice)

{

case 1: enter (); break;

case 2: delete1 (); break;

case 3: list (); break;

case 4: save (); break;

case 5: load (); break;

case 6: exit (0);

}

}

system ("pause");

return 0;

}

 

/* §нґцґалґзацґЯ списку. */

void init_list () {

register int t;

for (t = 0; t <MAX; ++t) addr_list [t].name[0] = '\0';

}

/* ЋтриманнЯ значеннЯ, вибраного в меню. */

int menu_select () {

char s [80];

int c;

printf ("1. ‚вести iм'Я \n");

printf ("2. ‚идалити iм'Я \n");

printf ("3. ‚ивести список \n");

printf ("4. ‡берегти файл \n");

printf ("5. ‡авантажити файл \n");

printf ("6. ‚ихiд \n");

do {

printf ("\n ‚ведiть номер потрiбного пункту: ");

gets (s);

c = atoi (s);

} while (c <0 || c> 6);

return c;

}

/* „одаваннЯ адреси в список. */

void enter () {

int slot;

char s [80];

slot = find_free ();

if (slot == -1) {

printf ("\n ‘писок заповнений");

return;

}

printf ("‚ведiть iм'Я: ");

gets (addr_list [slot].name);

printf ("‚ведiть вулицю: ");

gets (addr_list [slot].street);

printf ("‚ведiть мiсто: ");

gets (addr_list [slot].city);

printf ("‚ведiть Ћбласть: ");

gets (addr_list [slot].state);

printf ("‚ведiть поштовий iндекс: ");

gets (s);

addr_list [slot].zip = strtoul (s, '\0', 10);

}

/* Џошук вґльно» структури. */

int find_free () {

register int t;

for (t = 0; addr_list[t].name [0] && t <MAX; ++t);

if (t == MAX) return -1; /* вґльних структур нема№ */

return t;

}

/* ‚идаленнЯ адреси. */

void delete1 () {

register int slot;

char s [80];

printf ("‚ведiть Ь запису: ");

gets (s);

slot = atoi (s);

if (slot >= 0 && slot <MAX)

addr_list [slot].name [0] = '\0';

}

/* ‚ивґд списку на екран. */

void list () {

register int t;

for (t = 0; t <MAX; ++t) {

if (addr_list[t].name [0])

{

printf ("%s \n", addr_list[t].name);

printf ("%s \n", addr_list[t].street);

printf ("%s \n", addr_list[t].city);

printf ("%s \n", addr_list[t].state);

printf ("%lu \n \n", addr_list[t].zip);

}

}

printf ("\n \n");

}

/* ‡береженнЯ списку. */

void save () {

FILE *fp;

register int i;

if ((fp = fopen ("maillist", "wb")) == NULL) {

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

return;

}

for (i = 0; i <MAX; i++)

if (*addr_list[i].name)

if (fwrite (&addr_list[i], sizeof (struct addr), 1, fp)!= 1)

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

fclose (fp);

}

/* ‡авантажити файл. */

void load () {

FILE *fp;

register int i;

if ((fp = fopen ("maillist", "rb")) == NULL) {

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

return;

}

init_list ();

for (i = 0; i <MAX; i++)

if (fread (&addr_list[i], sizeof (struct addr), 1, fp)!= 1) {

if (feof (fp)) break;

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

}

fclose (fp);

}

 

”ункциЯ fseek()

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

fseek(fp, n, m);

–Я функцґЯ встановлю№ вказґвник у файлґ fp в позицґю, що вґдсто»ть на n байт вґд поточно», а напрЯмок перемґщеннЯ (вперед або назад) визнача№тьсЯ параметром m, Який може бути заданий одним з трьох значень: 0, 1, 2 або однґ№ю з трьох символьних констант, визначених у файлґ stdio.h:

- SEEK_SET = 0 С до початку файлу;

- SEEK_CUR = 1 С вказґвник на поточну позицґю у файлґ;

- SEEK_END = 2 С до кґнцЯ файлу.

”ункцґЯ fseek () використову№тьсЯ длЯ введеннЯ/виведеннЯ потоком. „лЯ роботи не з потоковими даними слґд використовувати функцґю lseek (). ЏґслЯ функцґ» fseek () можна виконувати операцґ» оновленнЯ у файлах, вґдкритих длЯ поновленнЯ. Џри вдалому завершеннґ роботи fseek () поверта№ нуль, в ґншому випадку функцґЯ поверта№ код помилки. ’одґ глобальна змґнна errno прийма№ одне з наступних значень:

- EBADF - невґрний вказґвник файлу;

- EINVAL - невґрний аргумент функцґ»;

- ESPIPE - пошук на пристро» заборонений.

Џри прЯмому доступґ можна виконувати операцґ» веденнЯ/виведеннЯ, використовуючи систему введеннЯ/виведеннЯ мови ‘ ґ функцґю fseek (), Яка встановлю№ вказґвник поточно» позицґ» у файлґ. Ћсь прототип цґ№» функцґ»:

int fseek (FILE <вказґвник файлу>, long int <кґлькґсть_байт>, <початок_вґдлґку>);

кґлькґсть_байт - кґлькґсть байтґв, рахуючи вґд початок_вґдлґку, воно визнача№ нове значеннЯ вказґвника поточно» позицґ», а початок вґдлґку - це один з наступних макросґв:

Џочаток вґдлґку - Њакрос

Џочаток файлу - SEEK_SET

Џоточна позицґЯ - SEEK_CUR

Љґнець файлу - SEEK_END

’ому, щоб отримати у файлґ доступ на вґдстанґ кґлькґсть_байт байтґв вґд початку файлу, початок_вґдлґку повинен дорґвнювати SEEK_SET. ™об при доступґ вґдстань вґдраховуваласЯ вґд поточно» позицґ», використовуйте макрос SEEK_CUR, а щоб при доступґ вґдстань вґдраховуваласЯ вґд кґнцЯ файлу, потрґбно вказувати макрос SEEK_END. Џри успґшному завершеннґ сво№» роботи функцґЯ fseek () поверта№ нуль, а в разґ помилки - ненульове значеннЯ.

“ наступнґй програмґ показано, Як використову№тьсЯ fseek (). „ана програма в певному файлґ вґдшуку№ деЯкий байт, а потґм вґдобража№ його. “ командному рЯдку потрґбно вказати ґм'Я файлу, а потґм потрґбний байт, тобто його вґдстань в байтах вґд початку файлу.

# 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 ("testr", "r")) == NULL) {

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

system ("pause");

exit (1);

}

fseek (fp, 6, SEEK_SET);

ch=fgetc (fp);

printf ("“ 6-му байтi мiститьсЯ ");

putchar (ch);

printf ("\n");

fclose (fp);

system ("pause");

return 0;

}

”ункцґю fseek () можна використовувати длЯ доступу всерединґ багатьох значень одного типу, просто множачи розмґр даних на номер елемента, Який вам потрґбен. Ќаприклад, припустимо, № список розсилки, Який склада№тьсЯ з структур типу addr (визначених ранґше). ™об отримати доступ до десЯто» адреси у файлґ, в Якому зберґгаютьсЯ адреси, використовуйте наступний оператор:

fseek (fp, 9 * sizeof (struct addr), SEEK_SET);

Џоточне значеннЯ вказґвника поточно» позицґ» у файлґ можна визначити за допомогою функцґ» ftell (). Ћсь»» прототип:

long int ftell (FILE <вказґвником файлу>);

”ункцґЯ поверта№ поточне значеннЯ вказґвника поточно» позицґ» у файлґ, пов'Язаному з вказґвником файлу вф. Џри невдалому результатґ вона поверта№ -1.

‡азвичай прЯмий доступ може знадобитисЯ лише длЯ двґйкових файлґв. Џричина тут проста - тому що в текстових файлах можуть виконуватисЯ перетвореннЯ символґв, то може ґ не бути прЯмо» вґдповґдностґ мґж тим, що знаходитьсЯ в файлґ ґ тим байтом, до Якого потрґбен доступ. ёдиний випадок, коли треба використовувати fseek () длЯ текстового файлу - це доступ до тґ№» позицґ», Яка була вже знайдена за допомогою ftell (); такий доступ викону№тьсЯ за допомогою макросу SEEK_SET, використовуваного в Якостґ початку вґдлґку.

„обре пам'Ятайте наступне: навґть Якщо в файлґ знаходитьсЯ один тґльки текст, все одно цей файл при необхґдностґ можна вґдкрити ґ в двґйковому режимґ. ЌґЯкґ обмеженнЯ, пов'Язанґ з тим, що файли мґстЯть текст, до операцґй прЯмого доступу не вґдносЯтьсЯ. –ґ обмеженнЯ стосуютьсЯ лише до файлґв, вґдкритих в текстовому режимґ.

”ункциЯ ftell()

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

long int i = ftell(fp);

Џоверта№ поточне значеннЯ вказґвника файлу fp (тобто номер поточно» позицґ») у виглЯдґ значеннЯ типу long int. ‚ґдлґк йде в байтах вґд початку файлу.

Џовернене значеннЯ може бути використане потґм у функцґ» fseek ().

џкщо виЯвленґ помилки, то функцґЯ поверта№ значеннЯ -1L ґ привласню№ глобальнґй змґннґй errno додатне значеннЯ.

# 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;

long int l;

FILE *fp;

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

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

system ("pause");

exit(1);

}

while (! feof (fp)) {

l = ftell(fp);

printf ("Ќомер поточно» позицi» %d перед зчитуваннЯм ", l);

fgets (str, 79, fp);

printf (str);

}

l = ftell(fp);

printf ("\n Ќомер поточно» позицi» %d пiслЯ зчитуваннЯ ", l);

printf ("\n");

fclose (fp);

system ("pause");

return 0;

}

”ункциЯ fscanf()

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

fscanf(fp, Control, arg1, arg2,..., argn);

”ункцґЯ чита№ данґ з файлу з вказґвником fp, перетворю№»х за форматами, записаними у керуючому рЯдку Control, ґ вґдформатованґ данґ запису№ в аргументи arg1,..., аrgn. „окладнґ вґдомостґ про роботу цґ№» функцґ» можна отримати, ознайомившись з роботою функцґ» scanf () (функцґю scanf ()).

”ункциЯ fprintf()

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

fprinf(fp, Control, arg1, arg2,..., argn);

‚иводить данґ в файл з вказґвником fp, перетворю№ аргументи arg1,..., аrgn до форматґв, Якґ записанґ в керуючому рЯдку Control, ґ вґдформатованґ данґ запису№ в файл. „окладнґ вґдомостґ про роботу цґ№» функцґ» можна отримати, ознайомившись з роботою функцґ» printf ().

Љрґм основних функцґй введеннЯ/виведеннЯ, про Якґ йшла мова, в системґ введеннЯ/виведеннЯ мови ‘ також № функцґ» fprintf () ґ fscanf (). –ґ двґ функцґ», за винЯтком того, що призначенґ длЯ роботи з файлами, ведуть себе точно так само, Як ґ printf () та scanf (). Џрототипи функцґй fprintf () ґ fscanf () наступнґ:

int fprintf (FILE * вф, const char * керуючий_рЯдок,...);

int fscanf (FILE * вф, const char * керуючий_рЯдок,...);

де вф - вказґвник файлу, що поверта№тьсЯ в результатґ виклику fopen (). Ћперацґ» введеннЯ/виведеннЯ функцґ» fprintf () ґ fscanf () виконують з тим файлом, на Який вказу№ вф.

‚ Якостґ прикладу пропону№тьсЯ розглЯнути наступну програму, Яка чита№ з клавґатури рЯдок ґ цґле значеннЯ, а потґм запису№»х у файл на диску; ґм'Я цього файлу Р test1. ЏґслЯ цього програма чита№ цей файл ґ виводить ґнформацґю на екран. ЏґслЯ запуску програми перевґрте, Яким вийде файл test1. џк ви ґ побачите, в ньому буде цґлком легкий длЯ читаннЯ текст.

/* Џриклад використаннЯ fscanf () ґ fprintf () */

# include <stdlib.h>

# include <stdio.h>

# include <windows.h>

# include <locale.h>

 

int main () {

setlocale(LC_CTYPE, "Russian");

FILE *fp;

char s [80];

int t;

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

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

system ("pause");

exit (1);

}

printf ("‚ведiть рЯдок i число: ");

fscanf (stdin, "%s %d", s, &t); /* читати з клавґатури */

fprintf (fp, "%s %d", s, t); /* писати в файл */

fclose (fp);

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

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

system ("pause");

exit (1);

}

printf("\n");

fscanf (fp, "%s %d", s, &t); /* читаннЯ з файлу */

fprintf (stdout, "%s %d", s, t); /* виведеннЯ на екран */

printf("\n");

fclose (fp);

system ("pause");

return 0;

}

Њаленьке попередженнЯ. •оча читати рґзносортнґ данґ з файлґв на дисках ґ писати»х у файли, розташованґ також на дисках, часто легше всього саме за допомогою функцґй fprintf () ґ fscanf (), але це не завжди найефективнґший спосґб виконаннЯ операцґй читаннЯ ґ запису. ’ак Як данґ в форматґ ASCII записуютьсЯ так, Як вони повиннґ з'ЯвитисЯ на екранґ (а не в двґйковому виглЯдґ), то кожен виклик цих функцґй пов'Язаний з певними накладними витратами. ’ому, Якщо треба пґклуватисЯ про розмґр файлу або швидкостґ, то, швидше за все, доведетьсЯ використовувати fread () ґ fwrite ().

”ункциЯ rewind()

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

rewind(<вказґвник_на_файл>);

‚становлю№ вказґвник поточно» позицґ» у файлґ на початок файлу. ‚иклик функцґ» rewind (<вказґвник_на_файл>) вґдповґда№ виклику функцґ» fseek (<вказґвник_на_файл>, 0L, SEEK_SET) за винЯтком того, що rewind () скида№ ґндикатор кґнцЯ файлу ґ ґндикатори помилок, а fseek () скида№ тґльки ґндикатор кґнцЯ файлу. ЏґслЯ функцґ» rewind () можна виконувати операцґ» оновленнЯ длЯ файлґв, вґдкритих длЯ поновленнЯ. ”ункцґЯ не поверта№ нґЯкого значеннЯ.

™об познайомитисЯ з rewind (), змґнимо програму, розглЯнуту ранґше, таким чином, щоб вона вґдображала вмґст файлу вґдразу пґслЯ його створеннЯ. ™об виконати вґдображеннЯ, програма пґслЯ завершеннЯ введеннЯ "перемоту№" файл, а потґм чита№ його з самого початку. ‡вернґть увагу, що зараз файл необхґдно вґдкрити в режимґ читаннЯ/запису, використовуючи Як аргумент режим, що зада№ рЯдок "w+".

 

# 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() - порґвнЯннЯ рЯдкґв

/* ’епер викону№тьсЯ читаннЯ ґ вґдображеннЯ файлу */

rewind (fp); /* встановити вказґвник поточно» позицґ» на початок файлу. */

while (! feof (fp)) {

fgets (str, 79, fp);

printf (str);

}

fclose (fp);

system ("pause");

return 0;

}

 

”ункциЯ remove()

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

int remove (< ґм'Я_файлу>);

”ункцґЯ видалЯ№ файл з ґм'Ям FILENameString. Џеред видаленнЯм файл повинен бути закритий. ђЯдок FILENameString повинен мґстити повний шлЯх до файлу. Џри нормальному завершеннґ завданнЯ функцґЯ поверта№ нуль, а в разґ помилки Р 1 (ненульове значеннЯ). Џри цьому глобальна змґнна errno прийма№ наступнґ значеннЯ:

- EACCES - заборонено видалЯти;

- ENOENT - нема№ такого файлу або директорґ».

Ќаступна програма вилуча№ файл. Ћднак спочатку вона да№ можливґсть передумати. “тилґта, подґбна цґй, може стати в нагодґ комп'ютерним користувачам-новачкам.

/* Џодвґйна перевґрка перед вилученнЯм. */

# include <stdlib.h>

# include <stdio.h>

# include <windows.h>

# include <locale.h>

# include <ctype.h>

 

int main() {

setlocale(LC_CTYPE, "Russian");

char str [80];

char filename[20]={"test"};

printf ("‚илучити файл test? (y/n):");

gets (str);

if (toupper (*str) == 'y')

remove (filename);

if (remove (filename)) {

printf ("Ќе можна вилучити файл. \n");

system ("pause");

exit (1);

}

system ("pause");

return 0;

}

 

”ункциЯ FILElength()

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

long FILElength(fp);

”ункцґЯ поверта№ довжину файлу з вказґвником fp в байтах. „лЯ роботи функцґ» потрґбно пґдключити файл io.h. “ випадку помилки функцґЯ поверта№ - 1, та глобальна змґнна errno набува№ значеннЯ EBADF - невґрний вказґвник файлу.

”ункциЯ ferror()

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

ferror(fp);

”ункцґЯ ferror() визнача№, чи вґдбуласЯ помилка пґд час виконаннЯ операцґ» з файлом. Џрототип цґ№» функцґ» наступний:

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

”ункцґЯ поверта№ значеннЯ true (ґстина), Якщо при останнґй операцґ» з файлом сталасЯ помилка, в ґншому ж випадку вона поверта№ false (неправда). ’ак Як при будь-Якґй операцґ» з файлом встановлю№тьсЯ своЯ умова помилки, то пґслЯ кожно» тако» операцґ» слґд одразу викликати ferror (), а ґнакше данґ про помилцґ можуть бути втраченґ.

“ наступнґй програмґ показано застосуваннЯ ferror (). Џрограма видалЯ№ табулЯцґ» з файлу, замґнюючи»х пробґлами. ђозмґр табулЯцґ» визнача№тьсЯ макросом TAB_SIZE. ‡вернґть увагу, що ferror () виклика№тьсЯ пґслЯ кожно» операцґ» з файлом.

/* Џрограма замґню№ в текстовому файлґ символи табулЯцґ» пробґлами ґ вґдслґдкову№ помилки. */

# include <stdlib.h>

# include <stdio.h>

# include <windows.h>

# include <locale.h>

# define IN 0

# define OUT 1

void err (int e);

 

int main() {

setlocale(LC_CTYPE, "Russian");

FILE *in, *out;

int i;

char ch;

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

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

system ("pause");

exit(1);

}

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

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

system ("pause");

exit(1);

}

do {

ch = fgetc (in);

if (ferror (in)) err (IN);

/* џкщо знайдена табулЯцґЯ, виводитьсЯ пробґл */

if (ch == '\t')

{

putc (' ', out);

if (ferror (out)) err (OUT);

}

else

{

putc (ch, out);

if (ferror (out)) err (OUT);

}

} while (!feof (in));

fclose (in);

fclose (out);

system ("pause");

return 0;

}

 

void err (int e) {

if (e == IN) printf ("Џомилка при введеннi. \n");

if (e == OUT) printf ("Џомилка при виведеннi. \n");

system ("pause");

exit (1);

}

 

”ункциЯ freopen()

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

FILE *freopen(const char *FILEname, const char *mode, FILE *stream);

”ункцґЯ пґдставлЯ№ файл, заданий в першому параметрґ, замґсть уже вґдкритого потоку. ‚она закрива№ потґк незалежно вґд того, чи вґдкритий вґн. –Я функцґЯ корисна длЯ замґни файлу, пов'Язаного зґ стандартними пристроЯми введеннЯ/виведеннЯ stdin, stdout або stderr. ‘пособи вґдкриттЯ файлу аналогґчнґ функцґ» fopen (). Џри успґшному завершеннґ функцґЯ поверта№ вказґвник типу FILE (Як ґ функцґЯ fopen ()), при неуспґшному - NULL.

Џриклад перенаправленнЯ потоку за допомогою функцґ» freopen () наведено в лґстингу 1.

Истинг 1

/* ЏеренаправленнЯ стандартного виводу у файл */

if (freopen ("OUTPUT.FIL", "w", stdout) == NULL)

fprintf (stderr, "error redirecting stdout \n");

/* –ей висновок пґде вже в файл */

printf ("This will go into a FILE.");

/* ‡акриттЯ стандартного потоку */

fclose (stdout);

”ункциЯ ferror()

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

ferror(FILE *fp);

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

if (ferror(fp)) { команди обробки помилок введеннЯ/виведеннЯ }

џк тґльки вґдбудетьсЯ помилка, викона№тьсЯ цЯ функцґЯ, ґ почнуть працювати команди обробки помилок.

”ункциЯ exit()

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

exit(int status);

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

„лЯ виклику функцґ» atexit () потрґбно пґдключити файл stdlib.h. Љожен виклик atexit () ре№стру№ нову функцґю exit (). Њожна заре№струвати до 32-х функцґй exit (). ‚они виконуватимутьсЯ за принципом роботи стеково» пам'Ятґ: "останнґй увґйшов - перший вийшов". ’обто останнЯ заре№стрована функцґЯ буде виконана першою. ЏоЯснимо сказане на прикладґ програми, наведено» в лґстингу 2.

Истинг 2

# include <stdio.h>

# include <stdlib.h>

/* –е перша функцґЯ exit () */

void exit_fn1 (void) {

printf ("Exit function # 1 called \ n");

}

/* –е друга функцґЯ exit () */

void exit_fn2 (void) {

printf ("Exit function # 2 called \ n");

}

/* ‚ основнґй програмґ вґдбува№тьсЯ ре№страцґЯ заданих ранґше функцґй exit (). ’ут же застосову№тьсЯ ґ сама функцґЯ exit (), Яка перед завершеннЯм роботи програми стане викликати цґ заре№строванґ ранґше функцґ» */

int main (void) {

/* ђе№страцґЯ першо» функцґ» */

atexit (exit_fn1);

/* ђе№страцґЯ друго» функцґ» */

atexit (exit_fn2);

/* Exit () спочатку викличе другу функцґю, тому що вона булла заре№стрована останньо», а потґм - першу функцґю. ЏґслЯ цього програма завершитьсЯ. */

exit (0);

return 0;

}

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





Поделиться с друзьями:


Дата добавления: 2016-09-06; Мы поможем в написании ваших работ!; просмотров: 387 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Лучшая месть – огромный успех. © Фрэнк Синатра
==> читать все изречения...

2257 - | 2144 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.011 с.