Файлы. Ввод/вывод
410.50K
Категория: ПрограммированиеПрограммирование

Файлы. Ввод-вывод

1. Файлы. Ввод/вывод

Понятие
ввода/вывода
является
важной
составляющей любого языка программирования.
Во
всех
примерах
рассмотренных
ранее
предполагалось,
что
ввод
в
программу
осуществляется с клавиатуры, а вывод направляется
на экран монитора.
Под вводом/выводом понимается процесс обмена
информацией между оперативной памятью и
внешними устройствами (клавиатура, дисплей,
магнитные и др. носители).
В случаях использования большого объема вводимых
и выводимых данных используют файлы.

2.

Всякая операция ввода/вывода трактуется
как операция обмена с файлами: ввод –
трактуется
как
чтение
из
файла
в
оперативную память, вывод – запись
информации из оперативной памяти в файл.
Ввод /вывод в С и С++ связан с понятием
потока.
Поток – это направленное движение
символов (или данных другого типа).
Существуют
стандартные
потоки
и
потоки,
объявляемые в программе, которые связываются с
файлами на диске.
Файлом называется именованная область внешней
памяти.

3.

Стандартные потоки cin, cout, cerr, stdin, stdout,
stderr.
Работа с файлами на диске начинается с объявления
указателя на поток (или используют термин
файловая переменная). Формат объявления:
FILE *имя_указателя;
FILE – стандартное имя структурного типа,
объявленного в заголовочном файле stdio.h
В структуре FILE содержится информация об
указателе на буфер, об указателе текущей позиции в
потоке и т.д.

4.

Язык С++ поддерживает обработку двух видов файлов:
текстовых и двоичных (бинарных).
Текстовым считается файл, в котором информация
запоминается в виде символов кода ASCII (или
аналогичном).
Он отличается от бинарного файла, который обычно
используется для запоминания кодов машинного языка.
Таким образом, содержимое текстового файла можно
просмотреть и изменить в любом текстовом редакторе.
Для чтения бинарного файла необходима специальная
программа.

5.

Текстовый файл – это последовательность символов
разделенная на строки специальными кодами –
возврат коретки (код 13) и перевод строки (код 10).
При чтении из файла комбинация этих символов
преобразуется в символ \n
При записи в текстовый файл осуществляется
обратное преобразование.
При работе с двоичными файлами никаких
преобразований
не
происходит,
информация
переносится без изменений.

6.

Открытие файла происходит с помощью функции
fopen( ), которая возвращает значение указателя на
поток.
Функция fopen имеет два параметра.
Первый аргумент – имя файла с которым будет
осуществляться работа.
Второй аргумент – указывает режим использования
файла (для текстовых файлов):
"r" – файл открыть для чтения,
"a" – открыть для дополнения,
придля
использовании
режима "r"
"w" – создать
записи
используется существующий файл
при использовании режимов "a" или "w"
если используется
"w" для уже
если файл не существует,
то существующего
он будет создан
файла, то старая версия файла затирается

7.

Дополнительные режимы:
"r+" – файл открыть для чтения и записи,
"a+" – открыть для дополнения или создать для
чтения и записи,
"w+" – создать для записи и чтения
Для работы с двоичными файлами используются
режимы:
"rb" и "r+b"
"ab" и "а+b"
"wb" и "w+b"
Если при открытии потока возникнет ошибка, то
функция fopen( ) возвращает значение NULL.
Ошибка может возникнуть из-за отсутствия
открываемого файла на диске, нехватки места в
динамической памяти и т.п.

8.

Поэтому в программах обработки файлов необходимо
контролировать
правильность
прохождения
процедуры открытия файла:
FILE *fp;
if ((fp=fopen("test.dat", "r"))= =NULL)
{ puts("Не возможно открыть \n");
return 1;
}
Закрытие потока осуществляет функция
fclose(fp);
Функция возвращает 0, если операция закрытия
прошла успешно, любое другое значение означает
ошибку.

9.

При работе с файлом используются понятия начало и
конец файла. При открытии файла, система помещает
файловый указатель на начало файла – его первый
элемент. При чтении информации в систему
передается первый элемент, и происходит сдвиг
указателя на следующий элемент.
Работа с файлом похожа на работу с массивом, размер
которого заранее не известен.
Указатель перемещается до тех пор, пока не будет
достигнут конец файла. Конец файла помечается
константой EOF (End of File), которая автоматически
формируется при закрытии файла, после записи в
него информации. Константа EOF возвращается
функцией feof( ) в случае достижения конца файла.

10.

Узнать, находится ли текущая позиция в конце файла,
можно с помощью функции feof
int feof(FILE *f);
FILE *f;
...
while (!feof(f)) {
int c = fgetc(f);
...
}
// цикл пока не конец файла
// прочесть очередное число
// . . .
// конец цикла

11.

Запись и чтение символов:
Функции putc( ) и putch( ) записывают один символ в файл.
Первый аргумент этих функций записываемый
символ, второй – указатель на файл.
int putc(int ch, FILE *fp); int putch(char ch, FILE *fp);
Различие этих функций в том, что первая работает с
целым типом, а вторая – с типом char.
При успешном выполнении записи в файл
возвращается записанный символ, в случае ошибки
возвращается константа EOF.

12.

Запись и чтение символов:
Функции getc( ) и getch( ) считывают один символ из
файла.
int getc(FILE *fp); char getch(FILE *fp);
При успешном считывании из файла функция
возвращает считанный символ, при достижении конца
файла возвращается значение EOF.
Прототипы этих функций содержатся в заголовочном
файле stdio.h.

13.

14.

15.

16.

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

17.

Прототип функции fscanf выглядит следующим
образом:
int fscanf(FILE *f, const char *format, ...);
Многоточие здесь означает, что функция имеет
переменное число аргументов, большее двух, и что
количество и типы аргументов, начиная с третьего,
произвольны. На самом деле, фактические аргументы,
начиная с третьего, должны быть указателями на
вводимые переменные.
int n, m; double a; char c; char str[256];
FILE *f;
...
fscanf(f, "%d", &n); // Ввод целого числа
fscanf(f, "%lf", &a); // Ввод вещественного числа
fscanf(f, "%c", &c); // Ввод одного символа
fscanf(f, "%s", str); // Ввод строки (выделяется очередное
// слово из входного потока)
fscanf(f, "%d%d", &n, &m); // Ввод двух целых чисел

18.

Функция fprintf используется для форматного вывода
в файл. Данные при выводе преобразуются в их
текстовое представление в соответствии с форматной
строкой. Ее отличие от форматной строки,
используемой в функции ввода fscanf, заключается в
том, что она может содержать не только форматы для
преобразования данных, но и обычные символы,
которые записываются без преобразования в файл.

19.

Прототип функции fprintf выглядит следующим
образом:
int fprintf(FILE *f, const char *format, ...);
Многоточие, как и в случае функции fscanf, означает,
что функция имеет переменное число аргументов.
Количество и типы аргументов, начиная с третьего,
должны соответствовать форматной строке.
int n = 4, m = 6; double x = 2.;
char str[256] = "Print test";
fprintf(f, "n=%d, m=%d\n", n, m);
fprintf(f, "x=%.4lf, sqrt(x)=%.4lf\n", x, sqrt(x));
fprintf(f, "Строка %s \n ",
str );

20.

Функции текстового преобразования sscanf и sprintf
Стандартная
библиотека
ввода-вывода
Си
предоставляет две замечательные функции sscanf и
sprintf ввода и вывода не в файл или поток, а в строку
символов, расположенную в памяти компьютера.
Мнемоника названий функций следующая: в названии
функции fscanf первая буква f означает файл (file), т.е.
ввод производится из файла; соответственно, в
названии функции sscanf первая буква s означает
строку (string), т.е. ввод производится из текстовой
строки. Первым аргументом функций sscanf и sprintf
является строка, из которой производится ввод или в
которую производится вывод. Эта строка как бы стоит
на месте файла в функциях fscanf и fprintf.

21.

Функции sscanf и sprintf удобны для преобразования
данных из текстового представления во внутреннее и
обратно. Например, в результате выполнения
фрагмента
char txt[256] = "-135.76"; double x;
sscanf(txt, "%lf", &x);
текстовая запись вещественного числа, содержащаяся
в строке txt, преобразуется во внутреннее
представление вещественного числа, результат
записывается в переменную x.

22.

Обратно, при выполнения фрагмента
char txt[256]; int x = 12345;
sprintf(txt, "%d", x);
значение целочисленной переменной x будет
преобразовано в текстовую форму и записано в строку
txt, в результате строка будет содержать текст "12345",
ограниченный нулевым байтом.

23.

Для
преобразования
данных
из
текстового
представления во внутреннее в стандартной
библиотеке Си имеются также функции atoi и atof с
прототипами
int atoi(const char *txt); // текст => int
double atof(const char *txt); // текст => double
Функция atoi преобразует текстовое представление
целого числа типа int во внутреннее. Соответственно,
функция atof преобразует текстовое представление
вещественного числа типа double.
Прототипы функций atoi и atof описаны в стандартном
заголовочном файле "stdlib.h":

24.

Для работы с бинарными файлами существуют
функции:
fread (buffer, size, count, stream )
Данная функция читает count элементов длины size из
входного потока (файла) stream (FILE *stream) и
помещает в заданный массив buffer.
При этом значение указателя файла увеличивается на
число действительно прочитанных байтов.
fwrite ( ) позволяет записывать в файл и имеет такие
же аргументы.
Функция дописывает count записей по size байтов
каждый из области buffer в выходной поток stream.

25.

Позиционирование в файле.
Установить текущую позицию в файле f можно с помощью функции
int fseek(FILE *f, long offset, int whence);
Первый аргумент функции f определяет файл, для которого
производится операция позиционирования.
Второй аргумент offset задает смещение в байтах, оно может быть как
положительным, так и отрицательным.
Третий аргумент whence указывает, откуда отсчитывать смещение.
Он может принимать одно из трех значений, заданных как целые
константы в стандартном заголовочном файле "stdio.h":
SEEK_CUR //смещение отсчитывается от текущей позиции
SEEK_SET //смещение отсчитывается от начала файла
SEEK_END // смещение отсчитывается от конца файла

26.

Например, фрагмент
fseek(f, 0, SEEK_SET);
устанавливает
текущую
позицию
в
начало
файла.
Фрагмент
fseek(f, -4, SEEK_END);
устанавливает текущую позицию в четырех байтах перед
концом файла.
Наконец, фрагмент
fseek(f, 12, SEEK_CUR);
продвигает текущую позицию на 12 байтов вперед.

27.

Узнать текущую позицию относительно начала файла
можно с помощью функции ftell с прототипом
long ftell(FILE *f);
Функция ftell возвращает текущую позицию
(неотрицательное значение) в случае успеха или
отрицательное значение -1 при неудаче (например,
если файл не разрешает прямое позиционирование).
English     Русский Правила