
Лаб по С и С++ / Лаб_С_№ 11
.doc/* ЛАБОРАТОРНАЯ РАБОТА 11 (IN_OUT)
ФУНКЦИИ ВВОДА И ВЫВОДА ВЕРХНЕГО УРОВНЯ
Функции ввода и вывода в стандартной библиотеке Си позволяют читать данные с клавиатуры, диска или порта ввода-вывода и выводить результат на терминал, диск или порт ввода-вывода.
Функции ввода/вывода делятся на группы:
1. ввод/вывод верхнего уровня
2. ввод/вывод системного уровня
3. ввод/вывод для консольного терминала
4. ввод/вывод через порт.
Для пользователя файл, открытый на верхнем уровне, представляется как последовательность считываемых или записываемых байтов. Чтобы отразить эту особенность, используется понятие "поток" (stream).
Функции ввода/вывода работают с буферизацией. Обмен информацией происходит не между программой и файлом, а между программой и буфером, расположенным в оперативной памяти.
Буферизация ускоряет работу программы из-за уменьшения количества обращений к внешним устройствам.
Чтобы получить доступ к файлу, необходимо связать его с соответствующей структурой типа FILE, объявленной в stdio.h и содержащей разнообразную информацию о файле. Эта операция называется открытием файла и осуществляется с помощью функции fopen, которая в качестве результата возвращает указатель на структуру FILE - указатель файла. Указатель файла в дальнейшем используется функциями для ввода/вывода информации в файл.
Указатель файла позиционируется в соответствии с открытием потока: если поток открыт для чтения - на начало файла, если для дозаписи - на конец файла. Указатель файла изменяется в соответствии с операцией записи или чтения.
После окончания ввода/вывода поток необходимо закрыть с помощью функции fclose или fcloseall, после чего указатель файла можно использовать для последующего открытия файла.
Потоки бывают текстовые или двоичные (по умолчанию - текстовые). При вводе текстового потока система Турбо Си преобразует символы возврат коретки и перевод строки в символ перевода строки, а при выводе текстового потока в среду операционной системы происходит обратное преобразование.
При вводе/выводе двоичного потока никаких преобразований не происходит.
При выполнении любой программы автоматически открываются пять стандартных потоков, имеющих следующие указатели файлов: stdin - поток ввода, stdout - поток вывода, stderr - поток вывода для сообщений об ошибках ( для вывода в поток stderr используется функция perror ), stdaux - последовательный порт и stdprn - устройство печати. Первые три потока по умолчанию связываются с консольным терминалом. Имена указателей стандартных потоков ввода/вывода могут указываться в функциях ввода/вывода.
Для переопределения стандартных потоков используется функция freopen.
Прототипы функций ввода/вывода описаны в stdio.h, и там же объявлен ряд макроопределений, в том числе NULL - нулевой байт, EOF - символ конца файла, BUFSIZ - размер буфера.
Далее приводятся описания прототипов функций с кратким пояснением.
Доступ к файлу
FILE * fopen(char *pathname, char *type);
функция открывает файл (имя задает первый аргумент) для
(второй аргумент):
"r" - чтения существующего файла
"w" - записи (перезаписи) файла
"a" - записи (дозаписи) файла
"r+" - чтения и записи существующего файла
"w+" - чтения и записи (перезаписи) файла
"a+" - чтения и записи (дозаписи) файла.
В конец строки записывается t - текстовый режим или b - дво-
ичный режим. Например: "rt" , "w+b".
Возврат при ошибке: NULL.
Закрытие потока
int fclose(FILE *stream);
int fcloseall(void);
Возврат при ошибке: EOF.
Конец файла
int feof(FILE *stream);
Возврат: 0 - не конец файла, иначе - конец файла.
Данные в файле могут быть организованы как:
1. непрерывный поток символов
2. последовательность строк переменной длины
3. форматированные поля, разделенные определенным символом
4. последовательность записей фиксированной длины.
В соответствии с этим разделим функции ввода/вывода верхнего уровня на группы.
Ввод/вывод символа
int getchar(void); - ввод из stdin
int putchar(int); - вывод в stdout
int fgetc(FILE *stream); - ввод из потока
int fputc(int c, FILE *stream); - вывод в поток
int getc(FILE *stream); - ввод из потока
int putc(int c,FILE *stream); - вывод в поток
int ungetc(char c, FILE *stream); - возврат введенного символа в поток.
Возврат при ошибке: EOF.
Построчный ввод/вывод
char * fgets(char *s,int n, FILE *stream); - cтрока из входного потока помещается в s (не более n-1 символа).
char * gets(char *s); - строка из stdin помещается в s.Возврат при ошибке: NULL.
int fputs(char *s, FILE *stream); - cтрока помещается в вы ходной поток.
int puts(char *s); - cтрока помещается в stdout.
Возврат при ошибке: EOF.
Форматный ввод/вывод
int fprintf(FILE *stream,<строка формата>,<список имен>); форматный вывод в поток.
int fscanf(FILE *stream,<строка формата>,<список адресов>); форматный ввод из потока.
int printf(<строка формата>,<список имен>); форматный вывод в stdout.
int scanf(<строка формата>,<список адресов>); форматный ввод из stdin. Ввод/вывод записей
int fread(void *bufer, int size, int count, FILE *stream); функция читает count элементов длины size из входного потока и помещает в bufer.
int fwrite(char *bufer, int size, int count, FILE *stream); функция дописывает count элементов длины size из области bufer в поток. Как правило, эти функции используются для ввода/вывода массивов и структур.
Внутреннее преобразование данных
int sprintf(char *s,<строка формата>,<список имен> ); вывод данных в строку.
int sscanf(char *s,<строка формата>,<список адресов>); ввод из строки по адресам.
Возврат при ошибке: EOF.
Прямой доступ к файлу
int fseek(FILE *stream, long offset, int origin); - функция перемещает указатель файла на offset позиций относительно начала файла, если origin равно 0, текущей позиции, если origin равно 1, конца файла, если origin равно 2. Если значение offset положительно - движение вперед, иначедвижение назад. Возврат при ошибке: не нуль.
Текущая позиция в файле
long ftell(FILE *stream); - возвращает номер текущей позиции от начала файла.
Пример 1.
/* создание копии autoexec.bat в autoexec.bak */
#include<stdio.h>
void main (void)
{
/* указатели входного и выходного потоков */
FILE *in, *out;
/* открытие входного потока */
if((in=fopen("\\autoexec.bat","rt"))==NULL)
{
fprintf(stderr, "cannot open input file\n");
exit(1);
}
/* открытие выходного потока */
if((out=fopen("autoexec.bak","wt"))==NULL)
{
fprintf(stderr, "cannot open output file\n");
exit(1);
}
/* символ из входного потока записать в выходной */
while(!feof(in))
fputc(fgetc(in), out);
/* закрытие потоков */
fclose(in);
fclose(out);
}
Пример 2.
/* внутреннее преобразование данных - из строки в float */
#include<stdio.h>
void main (void)
{
char s[20];
float chislo;
puts("\nввод числа");
gets(s);
sscanf(s,"%f",&chislo);
printf("полученное число %f\n", chislo);
}
Пример 3.
/* прямой доступ к файлу - печать 21-го символа из ес.bat */
/* в результате печатается n */
#include<stdio.h>
void main (void)
{
FILE *in, *out;
if((in=fopen("ec.bat","rt"))==NULL)
{
fprintf(stderr, "cannot open input file\n");
exit(1);
}
/* сместить указатель файла на 20 позиций от начала файла */
fseek(in,20L,0);
fprintf(stdout,"21-ый символ равен %c\n", fgetc(in));
}
/* содержимое ec.bat */
rrrrrrrrrrrrrrrrrrrdnyyyy
/* Порядок выполнения задания
1. Получить задание у преподавателя.
2. Проанализировать задачу.
3. Определить круг используемых функций.
4. Изучить необходимые функции.
5. Написать текст программы.
6. Разработать контрольный пример.
7. Провести отладку программы.
8. Выполнить программу.
9. Проверить правильность полученного результата.
/* ЗАДАНИЕ
Вариант 1
Даны два файла. Создать третий файл , объединяющий два файла в один. Имена файлов вводить по запросу.
Вариант 2
Дан файл. Имя файла не содержит расширения и задается с терминала по запросу. Создать копию файла. Имя файла-копии отличается от исходного тем, что имеет расширение bak. Использовать функцию strcat.
Вариант 3
Дан файл. Подсчитать количество слов в файле, начинающихся на букву а.
Вариант 4
Дан файл. Создать результирующий так, что он содержит каждый n-ый символ исходного файла, где n задается по запросу.
Вариант 5
Дан файл. Переписать его в обратном направлении.
Вариант 6
Программа производит ввод элементов матрицы из файла.
Вариант 7
Произвести вывод матрицы в файл.
Вариант 8
Исходный файл переписать таким образом, чтобы все буквы верхнего регистра были переведены в нижний регистр и наоборот. Использовать функции tolower, toupper, isupper.
Вариант 9
Дан файл. Подсчитать количество строк в файле и выдать номер самой длинной строки. Использовать функцию strlen.
Вариант 10
Дан файл. "Разрезать" исходный файл на несколько, каждый из которых содержит n строк, где n задается с терминала. Имя результирующих файлов должно быть связано с исходными. Использовать функцию strcat.
Вариант 11
Дан файл. Определить количество символов в файле и вывести на экран слово, стоящее посередине файла.