- •Программирование на языке высокого уровня си
- •Часть II
- •Содержание
- •Работа 1. Пользовательские функции в си
- •I. Теоретический раздел работы
- •1. Функции
- •1.1. Аргументы функций
- •1.2.Функции, возвращающие значения.
- •1.3. Функция main ()
- •2. Рекурсия.
- •II. Экспериментальный раздел работы
- •III. Задания для самостоятельной работы
- •Работа 2. Структурированный тип данных массив
- •I. Теоретический раздел работы
- •1.1. Структурированный тип данных массив
- •1.2. Передача массива в качестве параметра
- •1.3. Многомерные массивы
- •II. Экспериментальный раздел
- •III. Задания для самостоятельной работы.
- •Работа 3. Символьный и строковый типы данных
- •1.1. Символьный тип данных
- •Работа 4. Структуры
- •I. Теоретический раздел работы
- •1.1. Структура
- •1.2. Объединение
- •1.3. Переименование типов
- •II. Экспериментальный раздел работы
- •III. Задания для самостоятельной работы
- •Работа 5. Работа с файлами
- •I. Теоретический раздел работы
- •1.1.Введение
- •1.1. Потоковый ввод-вывод
- •1.2. Открытие и закрытие потока
- •1.3. Стандартные файлы и функции для работы с ними.
- •1.4. Форматированный ввод-вывод
- •1.5. Прямой доступ к файлам
- •II. Экспериментальный раздел работы.
- •III. Задания для самостоятельной работы
- •Список литературы
- •Учебное издание
- •Часть II
1.4. Форматированный ввод-вывод
В некоторых случаях информацию удобно записывать в файл без преобразования, т.е. в символьном виде пригодном для непосредственного отображения на экран. Для этого можно использовать функции форматированного ввода-вывода:
1) int fprintf(FILE *f, const char*fmt,. . .) , где
FILE*f – указатель на файл, в который производится запись,
const char*fmt – форматная строка,
. . . – список переменных, которые записываются в файл.
Функция возвращает число записанных символов.
2) int fscanf(FILE *f, const char*fmt, par1,par2, . . .) , где
FILE*f – указатель на файл, из которого производится чтение,
const char*fmt – форматная строка,
par1,par2,. . . – список переменных, в которые заносится информация из файла.
Функция возвращает число переменных, которым присвоено значении.
1.5. Прямой доступ к файлам
Рассмотренные ранее средства обмена с файлами позволяют записывать и считывать данные только последовательно. Операции чтения/записи всегда производятся, начиная с текущей позиции в потоке. Начальная позиция устанавливается при открытии потока и может соответствовать начальному или конечному байту потока в зависимости от режима открытия файла. При открытии потока в режимах “r” и “w” указатель текущей позиции устанавливается на начальный байт потока, при открытии в режиме “a” - за последним байтом в конец файла. При выполнении каждой операции указатель перемещается на новую текущую позицию в соответствии с числом записанных/прочитанных байтов.
Средства прямого доступа дают возможность перемещать указатель текущей позиции в потоке на нужный байт. Для этого используется функция
int fseek(FILE *f, long off, int org), где
FILE *f - – указатель на файл,
long off – позиция смещения
int org – начало отсчета.
Смещение задается выражение или переменной и может быть отрицательным, т. е. возможно перемещение как в прямом, так и в обратном направлениях. Начало отсчета задается одной из определенных в файле <stdio.h> констант:
SEEK_SET = =0 – начало файла;
SEEK_CUR= =1 – текущая позиция;
SEEK_END = =2 – конец файла.
Функция возвращает 0, если перемещение в потоке выполнено успешно, иначе возвращает ненулевое значение.
Примеры:
fseek(f,0L,SEEK_SET); //перемещение к началу потока из текущей позиции
fseek(f,0L,SEEK_END); //перемещение к концу потока из текущей позиции
fseek(f,-(long)sizeof(a),SEEK_SET); //перемещение назад на длину переменной а.
Кроме этой функции, для прямого доступа к файлу используются:
long tell(FILE *f);//получает значение указателя текущей позиции в потоке;
void rewind(FILE *f);//установить значение указателя на начало потока.
II. Экспериментальный раздел работы.
Пример 1: Посимвольный вывод содержимого файла на экран.
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
FILE *f;
char c;
char *filename=”f.txt”;
if((f=fopen(filename,”r”)==0)
{ perror(filename);
exit(0);
}
while(c=fgetc(f)!=EOF) putchar(c); //вывод с на стандартное устройство вывода
fclose(f);
}
Измените программу так, чтобы работа велась со строками.
Пример 2. Копирование содержимого файла.
…
int MAXLINE=255;//максимальная длина строки
FILE *in,//исходный файл
*out;//принимающий файл
char* buf[MAXLINE];//строка, с помощью которой выполняется копирование
in=fopen(“f1.txt”,”r”);//открыть исходный файл для чтения
out=fopen(“f2.txt”,”w”);//открыть принимающий файл для записи
while(fgets(buf,MAXLINE,in)!=0)//прочитать байты из файла in в строку buf
fputs(buf,out);//записать байты из строки buf в файл out
fclose(in);fclose(out);//закрыть оба файла
…
Поэкспериментируйте с предложенным отрывком программы, доработайте для копирования по следующей схеме A->B->C.
Пример 3. Создание базы данных сотрудников предприятия.
struct Employee
{
char name[30];
char title[30];
float rate;
};
void main()
{
Employee e;
FILE *f;
if((f=fopen(“f.dat”,”wb”))==NULL)
{
cout<<”\n Невозможно открыть файл для записи”;
exit(1);
}
int n;
//запись в файл
printf(“\nN-?”);
scanf(“%d”,&n);
for(int i=0;i<n;i++)
{
//формируем структуру е
printf(“\nname:”);scanf(“%s”,&e.name);
printf(“\ntitle:”);scanf(“%s”,&e.title);
printf(“\nrate:”);scanf(“%s”,&e.rate);
//записываеме в файл
fwrite(&e,sizeof(Employee),1,f);
}
fclose(f);
//чтение из файла
if((f=fopen(“f.dat”,”rb”))==NULL)
{
cout<<”\n Невозможно открыть файл для чтения”;
exit(2);
}
while(fread(&e,sizeof(Employee)1,f)
{
printf(“%s % s%f”, e.name, e.title, e.rate)
}
fclose(f);
}
Пример 4. Редактирование базы данных сотрудников предприятия
//добавление записи в файл
void add(char *filename)
{
student a;
int n;
f=fopen(filename,”a”)открыть файл для добавления
cout<<"\nHow many records would you add to file?";
cin>>n;
for(int i=0;i<n;i++)
{
прочитать объект
fwrite(&a,sizeof(student),1,f);//записать в файл
}
fclose(f);//закрыть файл
}
//удаление записи с номером х
void del(char *filename)
{
FILE *f, *temp;
f=fopen(filename,”rb”);//открыть исходный файл для чтения
temp=fopen(“temp”,”wb”)//открыть вспомогательный файл для записи
student a;
for(long i=0;.fread(&a,sizeof(student),1,f);i++)
if(i!=x)
{
fwrite(&a,sizeof(student)1,temp);
}
else
{
cout<<a<<" - is deleting...";
}
fclose(f);
fclose(temp);
remove(filename);
rename(“temp”, filename);
}
Измените программу, представленную в примере 3, используя предложенные подпрограммы.