Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C_Kurs_Lekt / C_II_семестр / 10-1_Файлы_пример_программ

.pdf
Скачиваний:
10
Добавлен:
13.02.2016
Размер:
79.95 Кб
Скачать

Лысый Д.А. Основыпрограммирования. Файлы. Примеры

1

ПРИМЕРЫ РАБОТЫ С ФАЙЛАМИ

Работа с файлом посимвольно:

#include <stdio.h> /* Программа ввода символов с консоли и записи их в файл*/ int main() {

FILE *fp; /* Указатель на поток */ char с;

const char CR='\13'; const char LF = '\10';

char fname[20]; /* Массив для имени файла */

puts("Введите имя файла: \n"); gets(fname); /* Запрос имени файла: */ if ((fp = fopen(fname,"w")) = NULL) /* Открыть файл для Записи: */

{ perror(fname); return 1; }

while ((c = getchar()) != '0') { /* Цикл ввода и записи в файл символов: */ if (с == '\n'){putc(CR, fp); putc(LF, fp);}

else putc(c, fp); }

fclose(fp); /* Цикл ввода завершен; закрыть файл: */ return 0; }

Следующая программа читает поток символов из ранее созданного файла и выводит его на экран дисплея:

#include <stdio.h> int main() {

FILE *fp; /* Указатель на поток */ char с;

char fname[20]; /* Массив для имени файла */ puts("введите имя файла: \n "); gets(fname);

if ((fp = fopen(fname,"r")) = = NULL) /* Открыть файл для чтения: */ { perror(fname); return 1; }

while ((c = getc(fp)) != EOF) /* Цикл чтения из файла и вывода символов на экран: */ putchar{c);

fclose(fp); return 0; }

Строковый обмен с файлами.

Пример программы, которая переписывает текст из одного файла в другой. Предположим, что мы хотим с ее помощью переписать содержимое файла f1.dat в файл f2.txt.

#include <stdio.h> main(){

char cc[256];/* Массив для обмена с файлами */ FILE *f1, *f2; /* Указатели на потоки */

if ((f1 = fopen("f1.dat", "r")) == NULL) { perror("f1.dat\n"); return 1; } if ((f2 = fopen("f2.dat", "w")) == NULL) { perror("f2.dat\n"); return 1; } while (fgets(cc, 256, f1) != NULL)

fputs(cc, f2);

fclose(f1); fclose(f2); return 0; }

Режим форматного обмена с файлами.

Программа, создающая файл int.dat и записывающая в него символьные изображения чисел от 1 до 10 и их квадратов:

#include <stdio.h> int main() {

FILE *fp; /* Указатель на поток */

 

 

 

int n;

 

 

 

 

 

 

if ((fp = fopen("int.dat","w")) ==

NULL) { perror("int.dat") ; return 1; }

for

(n=1; n<11;

n++)

fprintf(fp, "%d

%d\n", n,

n*n);

fclose(fp); return

0; }

 

 

 

 

Программа,форматного чтения данных из файла:

 

 

#include <stdio.h>

 

 

 

 

 

int main() {

 

 

 

 

 

FILE *fp; /* Указатель на поток */

 

 

 

int n, nn, i;

 

 

 

 

 

if ((fp = fopen("int.dat","r")) ==

NULL) { perror("int.dat") ; return 1; }

while (!feof(fp))

 

 

 

 

 

{ fscanf(fp,' "%d %d", &n,

&nn);

printf(" %d %d \n",n, nn); }

 

fclose(fp); return 0; }

 

 

 

 

Файлы произвольного доступа

Программы обработки файлов редко записывают в файл единственное поле. Обычно они записывают за один раз переменную типа struct.

Отдельные записи в файле с произвольным доступом обычно имеют фиксированную длину. Это позволяет получить к ним непосредственный (следовательно, быстрый) доступ без поиска по всем записям, т.е. можно вычислить точное положение записи относительно начала файла.

Размер одной записи, обычно, вычисляется оператором sizeof(struct type), в случае если все записи имеют фиксированную длину и не содержат ссылок.

Вычислить число записей в файле можно, используя следующий прием – вычисляем объем файла в байтах и делим его на размер одной записи:

while(1) {

 

 

 

 

 

fgetc(cfPtr);

/* cfPtr

– указатель

на поток связанный с

файлом */

if(feof(cfPtr)) break; /*

если данные исчерпаны –

то выход */

j++; }

/* переменная-счетчик

для подсчета

размера

файла */

Также, можно подсчитать объем сразу в записях: while(1) {

Лысый Д.А. Основыпрограммирования. Файлы. Примеры

2

if (fread(&its, sizeof(student), 1, cfPtr) == NULL) break; j++; } /* , где its – структура типа student */

Приведенные выше фрагменты теряют свою актуальность, если размер файла во время исполнения программы изменяется другим процессом. В этом случае можно использовать второй фрагмент, который обрабатывает записи последовательно, начиная с текущей позиции в файле и заканчивая последней.

while(1) {

if (fread(&its, sizeof(student), 1, cfPtr) == NULL) break;

{ /* обработка записей */ } }

Для перехода к произвольной записи можно использовать оператор fseek. Например: fseek(cfPtr, (Num -1) * sizeof(student), SEEK_SET);

Пример: программа для работы со списком студентов, способная хранить данные на диске и выводить их на печать (предусмотрена возможность корректировки данных).

Для удобства разобьем программу на несколько функций: Create_File – создает файл, заданного размера;

Udate_stud – позволяет обновлять данные указанных записей; Print_stud – считывает данные с диска и выводит на печать.

#include <stdio.h> #include <stdlib.h> #include <conio.h>

void Create_File(char *, int); void Udate_stud(char *, int); void Print_stud(char *);

typedef struct { int number; char name[15];

char surname[15];

long n_book; } student;

main () {

char *fn="stud.dat";

int kol_stud=5; /* первоначальное количество студентов */ clrscr();

Create_File( fn, kol_stud); /* создаем файл из пустых записей */ Udate_stud(fn, kol_stud); /* редактируем существующие записи*/ Print_stud(fn); /* распечатываем данные из файла */

return 0; }

/* Последовательное создание файла с произвольным доступом */ void Create_File(char *name, int kol) {

int i;

 

student its

= { 0,"","",0};

FILE *cfPtr;

 

if ((cfPtr =

fopen(name, "w")) == NULL) perror(name);

else {

for (i = 1; i <= kol; i++)

fwrite(&its, sizeof(student), 1, cfPtr); fclose(cfPtr); }

}

void Udate_stud(char *name, int kol) { FILE *cfPtr;

student its;

if ((cfPtr = fopen(name, "r+")) == NULL) perror(name); else {

printf("Введите номер студента (1 to %d, 0 - закончить ввод)?\n", kol); scanf("%d", &its.number);

while (its.number !=0) {

printf("Введите имя, Фамилию, номер зачетки ?\n"); scanf("%s%s %ld", &its.name, &its.surname, &its.n_book); fseek(cfPtr, (its.number-1)*sizeof(student), SEEK_SET); fwrite(&its, sizeof(student), 1, cfPtr); printf("Введите номер студента ?\n ");

scanf("%d", &its.number);

}

}

fclose (cfPtr);

}

void Print_stud(char *name) { FILE *cfPtr;

student its; int n,j=0;

if ((cfPtr = fopen(name, "r")) == NULL) perror(name); printf(" Список студентов группы?\n");

while (1)) {

if (fread(&its, sizeof(student), 1, cfPtr) == NULL) break; if (its.number !=0)

printf("%5d%17s%17s%10ld\n",its.number, its.name, its.surname, its.n_book);

}

fclose (cfPtr);

}