Организация работы с файлами
Язык Си, кроме стандартного ввода данных с клавиатуры и вывода результатов на экран, предоставляет также возможность обмена данными с файлами, находящимися на диске. В Си не предусмотрены никакие предопределенные структуры файлов (такие как файлы последовательного или прямого доступа); все файлы рассматриваются как последовательные, потоки битов.
Для файла определен маркер (указатель чтения/ записи). Он определяет текущую позицию, к которой осуществляется доступ. С началом работы любой программы автоматически открываются некоторые стандартные потоки, например, стандартный ввод (его имя –stdin) и стандартный вывод (его имя –stdout). По умолчанию они связаны с клавиатурой и экраном соответственно. Поэтому в тех функциях ввода/вывода, которые использовались до сих пор, не указывалось, из какого потока берутся или куда помещаются данные: это известно по умолчанию.
Однако, в своей программе возможно открыть и другие потоки, связывать их либо с файлами на диске, либо с физическими устройствами (например, с принтером), записывать в них или считывать из них информацию. Для этого служат функции ввода/вывода верхнего уровня. Доступ к потоку осуществляется с помощью указателя. Указатель на файл описывается следующим образом:
FILE *fp;
Тип FILE – это структура, определенная в < stdio> с помощью средства typedef и содержащая некоторую информацию о файле: например, флаги состояния файла, размер буфера, указатель на буфер и др. Описанный указатель можно связать с конкретным файлом в момент открытия данного файла. Это осуществляется с помощью функции
fopen(“путь к файлу”,”тип доступа”),
которая возвращает указатель на файл или NULL в случае ошибки.
Например, в результате выполнения оператора
fp=fopen(“ex1.txt”,”w”);
файл ex1.txt будет открыт для записи, а в программе на этот файл можно сослаться с помощью указателя fp (т.е. функция fopen() берет внешнее представление файла - его физическое имя - и ставит ему в соответствие внутреннее логическое имя, которое далее будет использоваться в программе). В качестве типа доступа могут быть указаны следующие параметры:
“w” –существующий файл открывается для записи, если файл не существовал, он создается заново, если существовал, то старое содержимое стирается.
“r” – файл открывается для чтения с начала.
“a” - файл открывается для дозаписи в конец файла.
(О других типах доступа можно прочитать в пособии по языку Си.[1].)
По окончании работы с файлом он должен быть закрыт. Для этого используется функция
fclose(указатель_файла).
Для чтения /записи данных в файл имеются функции, аналогичные уже известным функциям ввода/вывода
fprintf(),fscanf()? fputs(), fgets(), getc() putc(),getc(), ffputc().
Функции getc()/ fgetc(), putc()/fputc() по своим действиям идентичны, отличие состоит только в том, что getc() и putc() реализованы как макроопределения, а fgetc() и fputc(). - как настоящие функции.
Прототипы всех файловых функций, а также необходимые константы находятся в файле <stdio.h>.
Чтобы продемонстрировать работу с этими функциями, рассмотрим простой пример.
Пример 1.
# include<stdio.h>
void main()
{
int n;
char *str, str1[50],ch;
FILE *fp;
// Заполняем файл
fp=fopen(“D:\ex.txt”,”w+a”);
puts(“Введите целое число”) ;
scanf(“%d”,&n);
fprintf(fp, “%d\n” , n);
puts(“Введите символ”) ;
ch= getch ();
putc ( ch,fp);
puts(“Введите строку\n”) ;
scanf(“%s”, str);
fputs ( str, fp);
fclose ( fp);
// Читаем из файла
printf(“распечатка содержимого файла”);
if(( fp= fopen (“D:\ex.txt”,”r”)) != NULL)
{
fscanf (fp, “%d” ,&n);
printf( “n= %d\n” , n);
ch=getc ( fp ) ; putchar (ch );
fgets ( str1, 50 , fp); puts(str1 );
fclose ( fp );
}
else printf ( “\n Нельзя открыть файл для чтения !”);
}
Второй параметр функции fgets() – количество N считываемых символов, включая ‘\0’. Эта функция прекращает работу после чтения N-1 символа, либо после чтения ‘\0’. Функция fgets() возвращает либо адрес прочитанной строки, либо NULL по исчерпании файла или в случае ошибки.
В случае исчерпания файла или ошибки функция getc() возвращает EOF (End of FILE) – конец файла.
Функция fputs () возвращает код последнего прочитанного символа, если все в порядке, и EOF в случае ошибки. Эта функция не переводит строку автоматически.
Все приведенные выше функции обрабатывали файл последовательно символ за символом. Язык Си предоставляет возможность работать с файлом как с массивом: непосредственно достигать любого определенного байта. Для позиционирования файла служит функция.
fseek(указатель на файл, смещение от начальной точки, начальная точка ).
Второй аргумент имеет тип long. Его значение может быть больше и меньше нуля. Он показывает, как далеко (в байтах) следует продвинуться от начальной точки. Третий аргумент является кодом, определяющим положение начальной точки в файле. Установлены следующие значения кода: 0- начало файла, 1- текущая позиция, 2- конец файла. В случае успеха функция fseek() возвращает 0, а если была ошибка, то возвращается –1.
Так как язык Си связан с операционной системой UNIX, то в системе Borland C++ создана вторая система ввода/вывода. Эта система соответствует стандарту UNIX. Прототипы функций находятся в файле IO.H. Этими функциями являются
read() – читает буфер данных;
write()- пишет в буфер данных;
open()- открывает файл;
close()- закрывает файл;
lseek()- поиск определенного байта в файле;
unlink()- уничтожает файл.
Пример 2. Написать функцию, которая читает любое число байтов из любого меcта файла.
int get (int fd, long pos, char *buf, int n);
{
if ( lseek(fd, pos, 0)>=0) return read (fd, duf, n);
else return –1;
}
Задание на выполнение работы
1. Создайте текстовый файл в директории группы.
2. Введите программу примера 1. Выполните действия с заполнением и считыванием символов и строк.
3. Составить программу обработки текстового файла в соответствии с вариантом задания, представленного в таблице 7.1.
Таблица 7.1
Номер варианта | Вид обработки |
1.1 В текстовом файле подсчитать количество строк, которые оканчиваются заданной буквой (задается преподавателем). 1.2 Подсчитать количество слов в тексте 1.3 Посчитать количество символов нижнего регистра | |
2.1 В текстовом файле подсчитать количество строк, которые начинаются заданной буквой (задается преподавателем). 2.2 Посчитать количество строк в заданном тексте. 2.3 Подсчитать количество пробелов в тексте. | |
3.1 Найти максимальную длину строки в текстовом файле и распечатать все строки файла, имеющие такую длину. 3.2 Подсчитать количество печатных символов, отличных от пробела 3.3 Подсчитать количество пустых строк в файле. | |
4.1 Найти минимальную длину строки в текстовом файле и распечатать все строки файла, имеющие такую длину. 4.2 Подсчитать количество строк, начинающихся с определенной буквы латинского алфавита. 4.3 Подсчитать количество символов в строке с минимальной длиной. | |
5.1 Подсчитать количество строк, начинающихся с букв верхнего регистра. 5.2 Подсчитать количество печатных символов, отличных от пробела 5.3 Подсчитать количество пустых строк в файле. | |
6.1 Найти длину строки, лежащей в заданном пределе. 6.2.Соединить две строки в одну. 6.3.Подсчитать количество печатных символов, отличных от цифр | |
7.1 Найти строку, начинающуюся с заданной буквы. 7.2 Сравнить две строки 7.3 Подсчитать количество слов в заданной строке. | |
8.1 Найти строку, оканчивающуюся на заданную букву. 8.2. Подсчитать количество слов в заданной строке. 8.3 К первой строке присоединить n символов другой строки. | |
9.1 Подсчитать количество строк, начинающихся с букв нижнего регистра. 9.2. Найти самую длинную строку в тексте. 9.3. Подсчитать количество слов в тексте. | |
10.1 Найти минимальную длину строки в текстовом файле и распечатать все строки файла, имеющие такую длину. 10.2 Найти две идентичные строки 10.3 Подсчитать количество символов, отличных от перевода строки. | |
11.1 Найти максимальную длину строки в текстовом файле и распечатать все строки файла, имеющие такую длину 11.1 Подсчитать количество пробелов в тексте 11.3 Подсчитать количество слов в тексте | |
Продолжение табл.7.1 | |
12.1 В текстовом файле подсчитать количество строк, которые начинаются заданной буквой (задается преподавателем). 12.2 Посчитать количество строк в заданном тексте. 12.3 Подсчитать количество пробелов в тексте. | |
13.1 В текстовом файле подсчитать количество строк, которые имеющих одинаковую длину. 13.2 Посчитать количество слов в заданном тексте. 13.3 Подсчитать количество строчных букв в тексте. | |
14.1 Найти строку, оканчивающуюся на заданную букву. 14.2. Подсчитать количество слов в заданной строке. 14.3 К первой строке присоединить n символов другой строки. | |
15.1 Найти строку, начинающуюся с заданной буквы. 15.2 Найти строку идентичной заданной 15.3 Подсчитать количество слов в тексте. |
Содержание отчета
1. Краткие теоретические сведения о методах обработки потоков данных.
2. Программа обработки, распечатки файлов с данными.
3. Комментарии к программе и полученным результатам
Контрольные вопросы
1. Что такое поток данных?
2. В чем состоит различие ввода данных в стандартном потоке и с внешнего устройства?
3. Напишите команды открытия файла для чтения и записи, закрытия файла.
4. В чем состоит различие команд fputs() и fgets()?
Работа №8
Обработка списков
Цель работы: освоение методов обработки линейных и дважды связанных списков, приобретение навыков составления и отладки соответствующих программ