Практика программирования (Бейсик, Си, Паскаль)

       

Основные типы файлов в Си


Система программирования Borland С поддерживает работу с файлами и потоками, данные в которых представлены либо в символьном, либо в двоичном формате. Однако все ранее описанные типы файлов доступны и в программах на Си.

Текстовые (строковые) файлы в Си

Текстовый файл в Си может быть создан путем записи на диск символьных и/или числовых данных по заданному формату с помощью оператора fprintf. В качестве признака конца строки здесь заносятся те же самые байты ODOA, которые появляются на диске в результате вывода управляющего символа \п.

Для инициализации текстового файла необходимо завести указатель на структуру типа FILE и открыть файл в одном из нужных режимов ("rt" для ввода, "wt" - для вывода, "at" — для дозаписи в уже существующий набор данных) по оператору f open:

FILE *f1;

f1=fopen(имя_файла, "режим");

Формат оператора вывода данных в текстовый файл таков:

fprintf(f1,"список_форматов \n",список_вывода);

Если очередная строка текстового файла формируется из значения элементов символьного массива str, то вместо оператора fprintf (fi, "%s\n",str) проще воспользоваться оператором fputs (f1, str).

Чтение данных из текстового файла осуществляется с помощью оператора fscanf(f1,"список_форматов", список_ввода) или fgets(str,n,f1). В последней функции параметр n означает максимальное количество считываемых символов, если раньше не встретится управляющий байт ОА.

В Си существуют и другие возможности для работы с текстовыми файлами — функции open, creat, read, write,

Программа 7_02.с

#include <stdio.h>



#include <stdlib.h>

#include <math.h>

main( ) {

FILE *f;

int j,k;

float d;.

char s[7]="Строка";

f=fopen("c_txt","wt");

for(j=l;j<11;j++)

{

fprintf(f,"%s %d %f\n",s,j,sqrt(j));

fprintf("\n Строка %d %n",j,sqrt(j)); }

fclose(f); fprintf("\n");

f=fopen("c_txt","rt");




for(j=10; j>0; j--) {

fscanf(f,"%s %d %f",s,&k,&d);

fprintf("\n%s %d %f",s,k,d); }

getch () ; }

Обратите внимание на возможную ошибку при наборе программы 7_01.с. Если между форматными указателями %з и %d не сделать пробел, то в файле текст "строка" склеится с последующим целым числом. После этого при чтении в переменную s будут попадать строки вида "строка!", "строка2", ..., "строкаю", в переменную k будут считываться старшие цифры корня из j (до символа "точка"), а в переменной d скажутся дробные разряды соответствующего корня.

Записеориентированные файлы в Си

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

Для инициализации записеориентированного файла необходимо завести указатель на структуру типа FILE и открыть файл в одном из нужных режимов ("rb" — для ввода, "wb" — для вывода, "ab" — для дозаписи в уже существующий набор данных) по оператору f open:

FILE *f11;

f1=fopen(имя_файла, "режим");

Формат оператора вывода данных в записеориентированный файл таков:

fwrite(buf, size_rec, n_rec, f1) ;

Здесь size_rec — размер записи в байтах, а п_гес — количество записей, участвующих в обмене. Считывание данных из записеориентированного файла осуществляется с помощью функции f read:

fread(buf, size_rec, n_rec, f1);

Программа 7_02.с в цикле формирует значение записи b, состоящей из символьного (b.s, 7 байт, включая нулевой байт — признак конца строки), целочисленного (b.n, 2 байта) и вещественного (b.r, 4 байта) полей, и выводит содержимое полей на диск последовательными порциями. Затем файл открывается для ввода и содержимое записей извлекается в обратном порядке. Второй аргумент функции fseek определяет величину смещения указателя файла в байтах относительно точки, заданной третьим параметром. Параметр SEEK_SET означает, что сдвиг указателя в файле производится от его начала. Для сдвига от конца файла используется константа SEEK_END, а для сдвига относительно текущей позиции — константа SEEK_CUR.



Программа 7_03.с

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <string.h>

main( ) {

FILE *fl; int j, k;

struct { char s [7]; int n; float r; } b;

clrscr();

strcpy(b.s,"Строка");

fl=fopen("c_rec","wb");

for(j=l;j<ll;j++)

{

b.n=j; b.r=sqrt(j);

fwrite(&b,sizeof(b),l,fl);

printf("\n%s %d %f",b.s,b.n,b.r);

}

fclose(fl); printf("\n");

fl=fopen("c_rec","rb");

for(j=10; j>0; j —) {

fseek(fl,(j-1)*sizeof(b),SEEK_SET);

fread(&b,sizeof(b),l,f1);

printf("\n%s %d %f",b.s,b.n,b.r);

}

getch();

}

Двоичные файлы в Си

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

Кроме набора функций {fopen/fciose, fread/fwrite}, для работы с двоичными файлами в библиотеке Borland С предусмотрены и другие средства -

{_dos_open/_dos_close, _dos_read/_dos_write}, (_creat/_close, _read/_write}.

Однако знакомство со всеми возможностями этой библиотеки в рамках настоящего пособия не предусмотрено.

Программа 7_04.с

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

main ( ) {

FILE *f1; int j, k;

char s[7]="Строка";

int n;

float r; clrscr. () ;

fl=fopen("c_bin","wb");

for(j=l;j<11;j++) {

r=sqrt(j);

fwrite(s,sizeof(s),1,f1);

fwrite(&j,sizeof(int),1,f1);

fwrite(&r,sizeof(float),1,f1);

printf("\n%s %d %f",s,j,r); }

fclose(f1l); printf("\n"); fl=fopen("c_rec","rb"); for(j=10; j>0; j--) {

fseekffl,(j-1)*(sizeof(s)+sizeof(int)+sizeof(float)),

SEEK_SET);

fread(&s,sizeof(s),1,fl);

fread(&n,sizeof(int),1,f1);

fread(&r,sizeof(float),1,f1);

printf("\n%s %d %f",s,n,r); }

getch(); }




Содержание раздела