C_Kurs_Lekt / C_II_семестр / 10-1_Файлы_пример_программ
.pdfЛысый Д.А. Основыпрограммирования. Файлы. Примеры |
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);
}