4. КОНТРОЛЬНЫЕ ВОПРОСЫ
4.1. Какие типы данных относятся к простым, какие к составным?
4.2. Как объявляются структуры и чем отличается структура от массива?
4.3 Как обращаться к полям структуры?
4.3. Какие операции допустимы над структурой в целом?
Лабораторная работа № 9
Программные средства для работы с файлами
1. ЦЕЛЬ РАБОТЫ: изучение файловых типов данных, приобретение практических навыков создания и обработки текстовых файлов.
2. ОСНОВНЫЕ ПОНЯТИЯ
Файл - это упорядоченная последовательность однотипных компонентов, расположенных на внешнем носителе. Файлы предназначены только для хранения информации, а обработка этой информации осуществляется программами. Использование файлов целесообразно в случае:
- долговременного хранения данных;
- доступа различных программ к одним и тем же данным;
- обработки больших массивов данных, которые невозможно целиком разместить в оперативной памяти компьютера.
Файл, не содержащий ни одного элемента, называется пустым. Создается файл путем добавления новых записей в конец первоначально пустого файла. Длина файла, т.е. количество элементов, не задается при определении файла. При вводе и выводе данные рассматриваются как поток байтов. Физически поток – это файл или устройство (клавиатура или дисплей). В Си поток можно открыть для чтения и/или записи в текстовом или бинарном (двоичном) режиме. В текстовых файлах не употребляются первые 31 символ кодовой таблицы ASCII (управляющие), а символы конца строки 0x13 (возврат каретки, CR) и 0x10 (перевод строки LF) преобразуются при вводе в одиночный символ перевода строки \n (при выводе выполняется обратное преобразование). Эти символы добавляются в конце каждой строки, записываемой в текстовый файл. При обнаружении в текстовом файле символа с кодом 26 (0x26), т.е. признака конца файла, чтение файла в текстовом режиме заканчивается, хотя файл может иметь продолжение.
В двоичном режиме эти преобразования не выполняются, чтение продолжается, пока не встретится физический конец файла. При чтении символы не преобразуются и не анализируются.
Функция открытия потока fopen возвращает указатель на предопределенную структуру типа FILE (содержащую всю необходимую для работы с потоком информацию) при успешном открытии потока, или NULL в противном случае.
В заголовочном файле stdio.h содержится описание файлового типа FILE, с которым связывается файловая переменная (указатель на файл). При открытии файла указатель на файл связывается с конкретным файлом на диске и определяется режим открытия файла:
r (r+) - файл открывается для чтения (чтения и записи);
w (w+) - открывается пустой файл для записи (чтения и записи). Если файл с таким именем существует, он стирается;
a (а+)- файл открывается для дополнения в конец (чтения и дополнения).
Режим открытия может также содержать символы t (текстовый файл) и b (двоичный файл), указывающий на вид открываемого файла: rb, wb, ab, rt, at, rb+, wb+, ab+ и т.д.
Закрытие файла (текстового или бинарного) выполняется функцией fclose(), установка указателя на начало файла - функцией rewind(). Если при попытке чтения данных из файла встречается символ конца файла, то возвращается специальное значение EOF. Функции feof(),ferror() сообщают о причинах, по которым операция ввода/вывода не выполнилась. Запись данных в файл и чтение данных из файла можно выполнять разными способами:
1) функциями форматного ввода-вывода fscanf(), fprintf();
2) функциями неформатного ввода-вывода fread(), fwrite().
Если требуется сохранять и восстанавливать числовые данные без потери точности, то лучше использовать fread(), fwrite(). Если обрабатывается текстовая информация, которая будет просматриваться обычными текстовыми редакторами, то используется fgetс()- посимвольное чтение файла, посимвольная запись в файл - fputc() или функции fscanf(), fprintf(). Для чтения из файла и записи в файл строки используются функции fgets() и fputs().
Пример программы с использованием текстовых файлов
Создать текстовый файл "new1.txt" записав в него строку из 50 символов. Все символы, отличные от пробела, переписать в новый файл "new2.txt":
//lab9_1
#include <stdio.h>
#include <conio.h>
#include <string.h>
main()
{ char ch, sl[50];
char text[]="one to tree four";
FILE *pf, *pr; // Указатели на файлы
pf=fopen("new1.txt","w"); // Создание нового файла new1.txt
clrscr();
fprintf(pf,"%s\n",text); // Запись в файл строки text
fclose(pf); // Закрытие файла pf
pf=fopen("new1.txt","r"); // Открытие файла pf для чтения
pr=fopen("new2.txt","w"); // Создание нового файла new2.txt
while (!feof(pf)) // Пока не конец файла
{ ch=getc(pf); // Чтение символа ch из файла pf
if (ch != ' ')
putc(ch,pr); // Запись в файл pr символа ch
}
fclose(pr); // Закрытие файла pr
rewind(pf); // Возврат указателя на начало файла pf
fgets(sl,50,pf); // Чтение из файла pf строки в переменную sl
printf("%s\n",sl); // Вывод строки sl на дисплей
pr=fopen("new2.txt","r"); // Открытие файла pr для чтения
while (!feof(pr)) // Пока не конец файла pr
{ ch=getc(pr); // Чтение символа из файла pr
putchar(ch); // Вывод символа ch на дисплей
}
fclose(pf); // Закрытие файлов
fclose(pr);
getch();
}
При чтении текстовых файлов лучше использовать функции getc или fgetc, так как при использовании fscanf (pr, “%s”, sl) читается только очередное слово до пробела или символа табуляции и требуется повторение этой функции многократно для других слов.
3. ВЫПОЛНЕНИЕ РАБОТЫ
3.1. Разобрать и проанализировать приведенную программу.
3.2 . Создать текстовый файл из 5 строк, прочитать созданный файл и получить новый файл согласно своему варианту.
Варианты заданий
1. Из строк все цифры переписать в новый файл.
2. Переписать все строки в новый файл, заменив пробелы на запятые.
3. Переписать в новый файл все символы из строк, отличные от цифр.
4. Подсчитать количество слов в каждой строке и записать их в новый файл.
5. Переписать все строки в новый файл, заменив все буквы 'м' на 'М'.
6. В новом файле заменить все цифры на восклицательные знаки.
7. Переписать все латинские буквы верхнего регистра из каждой строки в новый файл.
8. Переписать в новый файл строки, удалив из них все русские буквы нижнего регистра.
9. В новом файле заменить все латинские буквы верхнего регистра на буквы нижнего регистра.
10. Переписать в новый файл все строки, заменив все русские буквы нижнего регистра на буквы верхнего регистра.
11. Все слова, начинающиеся с гласных переписать в один файл, а с согласных – в другой новый файл.
12. В новый файл переписать каждую строку наоборот.
4. КОНТРОЛЬНЫЕ ВОПРОСЫ
4.1. Чем отличается файл от массива?
4.2. Особенности организации текстовых файлов.
4.3. Что понимается под чтением, и что под записью в файл?
Лабораторная работа № 10
Обработка бинарных файлов
1. ЦЕЛЬ РАБОТЫ: приобретение практических навыков создания и обработки бинарных файлов.
2. ОСНОВНЫЕ ПОНЯТИЯ
Если файл открыт в бинарном режиме, его можно записывать или считывать побайтно. Функция fseek() позволяет обращаться с файлом как с массивом и переходить к любой позиции в файле, обеспечивая возможность произвольного доступа. Если текстовые файлы являются файлами с последовательным доступом, то произвольный доступ чаще всего применяется к бинарным файлам.
Бинарные файлы могут содержать любую информацию. Чаще всего используются файлы, содержащие структуры. Для чтения и записи в бинарные файлы можно использовать функции fread(), fwrite() или fscanf(),fprintf().
fread –функция для чтения из файла:
int fread(void *ptr, unsigned size, unsigned count, FILE *f);
Из файла f считываются и по адресу ptr записываются count элементов размером size каждый. Функция возвращает число фактически считанных элементов.
fwrite – функция для записи в файл:
int fwrite(void *ptr, unsigned size, unsigned count, FILE *f);
В файл записываются, начиная с адреса ptr, count элементов размером size каждый. Функция возвращает число фактически записанных элементов.
fseek – функция для произвольного доступа к байтам бинарных файлов:
int fseek(FILE *f, long offset, int w);
offset показывает, на сколько байт нужно сместиться относительно точки отсчёта – w.
w должно быть равно одной из трех констант:
SEEK_SET или 0 - начало файла;
SEEK_CUR или 1 – текущая позиция в файле;
SEEK_END или 2 – конец файла.
ftell - возвращает текущую позицию в файле как длинное целое:
long int ftell (FILE *f);
Составить программу, выполняющую следующие функции:
1. Создание нового файла;
2. Просмотр файла;
3. Добавление информации в конец файла;
4. Поиск по названию товара и изменение цены и количества;
Файл создать из структур вида: название товара, его цена и количество.
Задание выполнить в отдельных функциях. Использовать меню для выбора функций.
//lab10_1
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct tov {char name[10]; float c; int kol;} t1;
void input(FILE *); // создание нового файла
void print(FILE *); // просмотр файла
void app(FILE *); // добавление в файл
void find(FILE *); // поиск и изменение
main()
{ char c;
FILE *tf;
while (1)
{ clrscr();
puts(" 1 – новый файл");
puts(" 2 – просмотр файла");
puts(" 3 – добавление в файл");
puts(" 4 – поиск и изменение");
puts(" 0 - выход");
c=getch();
switch(c)
{ case '1':input(tf);break;
case '2':print(tf);break;
case '3':app(tf);break;
case '4':find(tf);break;
case '0':return 0;
default : puts(" неверный режим");
}
}
}
void input(FILE *tf)
{ char ch;
tf=fopen("file1.dat","wb"); // открытие бинарного файла для записи
clrscr();
printf("\n Ввод товаров\n");
do
{ printf("\n название: "); scanf("%s",t1.name);
printf(" цена: "); scanf("%f",&t1.c);
printf(" количество: "); scanf("%d",&t1.kol);
fwrite(&t1,sizeof(t1),1,tf); // запись в файл одной структуры t1
printf("\n Закончить? y/n ");