Автор: Пользователь скрыл имя, 07 Декабря 2011 в 22:34, лекция
Лекции по информатике.Потоки+нижний уровень
1.7. Файловый ввод-вывод в стиле языка С.
1.7.1. Файловый ввод-вывод с помощью потоков в стиле языка С.
1.7. Файловый ввод-вывод в стиле языка С.
1.7.1. Файловый ввод-вывод с помощью потоков в стиле языка С.
Виды доступа:
Текстовый файл (режим) | Двоичный (бинарный) файл | |
Открытие файла | r
rt |
rb |
Создание файла для записи, если он был, то он будет очищен | a
at |
wb |
Открытие или создание файла для записи в конец | a+
at+ |
ab |
Открытие существующего файла по чтению/записи с любой позиции | r+
rt+ r+t |
rb
rb+ r+b |
Создание пустого потока. Если в качестве потока будет уже существующий файл, то он будет очищен | w+
wt+ w+t |
wb+
w+b |
Открытие или создание файла для чтения или записи только в конец файла | a+
at+ a+t |
ab+
a+b |
Пример чтения из потока:
#include <stdio.h>
int main(void)
{ FILE *potok ;
char ch ;
potok = fopen ( “Myfile.dat”, “r” ) :
do
{ ch = fgetc(potok);
printf (“%c”, ch); // вывод на экран считанного из файла символа
}
while ( ch != EOF );
fclose (potok);
return 1;
}
Пример ввода строки символов, например, наименования оборудования, переменной длины из файла, контроль окончания стоки символ «\0»:
…
FILE *potok ; int j;
Char name [20]; // Считаем, что длина наименование объекта не более 20 символов;
potok = fopen ( “Myfile Dat A1”, “r” )
while (! feof(potok))
{ j=0;
while (name[j]) // контроль достижение символа “/0”
{ name [j] = getc (potoл); j++; }
printf (“%20s\n”,name);
}
Пример ввода строки символов из файла, например, наименования оборудования, с требованием постоянной длины:
#include <stdio.h>
void main(void)
{ FILE *potok ;
Char name [20]; // Считаем, что длина наименование объекта не более 20 символов;
potok = fopen ( “Myfile Dat A1”, “r” )
while (! feof(potok))
{ fgets (name, 21, potok );
printf (“%20s\n”,name);
}
}
Пример заполнение многостраничного окна редактирования Memo в интегрированный системе визуального программирования Builder C++:
#include <stdio.h>
FILE * f;
…
if (( f=fopen (“c:\data.tmp”, “rt”)) == NULL
{ ShowMassage(“Файл не открыт”); return; }
…
char s[80]; MyMemo->clear; // чистка многостраничного окна редактирования
do
{ fgets( s, 80, f ); // чтение по 80 символов из файла c:\data.tmp
if (feof (f)) brak; // контроль конца файла
if (s[strlen (s)-1]==”\n”) // контроль конца считанной строки
d[strlen(s)-1] = 0; // данная операция не обязательна, но наличие символа “/n”
MyMemo->Lines->Add(s); /
}
fclose(f); // сервисная функция закрытия потока, ее расширение функция
…
Пример поиска слова в файле в интегрированный системе визуального программирования Builder C++:
char s[80]; key[10];
strcpy (key, MyEdit->Text.c_str()); // В массив символов загрузили слово из окна Edit
do
{
fscanf( f, “%s”, &s); // чтения одного слова переменной длины из потока
if (feof(f))||strcmp(s,key)) // сравнение эталона с введенным словом плюс
break;
}
while (true); // «вечный» цикл
fclose(f);
if (strcmp (s, key)) ShowMessage
(“Слово найдено!”);
Пример чтения из файла в структуру, где первый элемент содержит наименование оборудования переменой длины (не допускает пробелов), а второй элемент структуры отображает стоимостью оборудования:
#include ,stdio.h>
int main(void)
{ FILE * f; int j;
struct {char name[20]; float stoim;} obor;
f = fopen (“d:\data.tmp”, ”r”);
while (!feof(f))
{ j=0;
while (obor.name[j])
{ obor.name[j]=getc(f);
j++; }
fscanf(f, “%f”\n”, &obor.stoim; }
fclose(f);
return 1;
}
Пример записи в файл наименование оборудования, которое может быть длиной до 20 символов. Отметим, что хотя длины строки может быть переменной, ввод пустого символа не допускается при такой организации:
#include <stdio.h>
void main(void)
{ FILE *stream; int j=0;
char Name [20];
printf(“%s\n”,”Введите наименование оборудования”);
scanf(“%20s”, &Name);
stream = fopen(“MeFile D A1”,”a+”);
fseek(stream, 0L, SEEK_END);
while(Name[j])
{ fputc(Name[j], stream); j++; }
fclose(stream);
return;
}
Пример одновременного обращения к дисковому файлу по чтению-записи:
#include <stdio.h>
void main(void)
{ FILE *stream; char first;
stream = fopen (“MyFile.$$$”, “a+”);
fprintf (stream, “Строка пирмера”);
rewind (stream);
fscanf(stream, “%c”, & first);
cprintf ( “ Первый символ, записанный в файле MyFile.$$$ = %c”, first);
fclose(stream);
return;
}
Пример посимвольной записи в двоичный файл. Количество передаваемых байт определяется длиной строки strlen (s) +1, где один символ добавлен для записи в отток нулевого символа “\0”.
int i = 1, j;
char s[10], s1[10];
strcpy (s, “Иванов”);
FILE * potok;
if (( potok = fopen (“test.tmp”, “wb”)) == NULL)
{ ShowMessage ( “Ошибка открытия файла”); return; }
fwrite( &i, sizeof(int), 1, potok); // запись порядкового номера
fwrite( s, sizeof (char), strlen (s) +1, potok ); // после номера запись длины строки
fclose(potok);
if (( potok = fopen (“test.tmp”, “rb”)) == NULL)
{ ShowMessage ( “Ошибка открытия файла”); return; }
fread( &j sizeof(int), 1, potok);
fread( s1, sizeof (char), strlen (s) +1, potok );
fclose(potok);
1.7.2. Ввод-вывод функциями нижнего уровня, через дескрипторы.
Главным достоинством данного подхода является, то, что чтение/запись производятся без буферизации. Второе достоинство – работа с дескрипторами реализуется во всех современных интегрированных системах разработки программ, в том числе и в СУБД, например, «MS Access», Clipper , что позволяет обеспечить межпрограммный интерфейс. Недостаток работы с файлами через дескрипторы - это отсутствие форматирования и большие временные затраты чтения-записи по сравнению с другими способами.
Стандартные
потоки языка С++ сразу имеют свои
дескрипторы с
Stdin 0
Stdaut 1
Stderr 2
Для работы через дескрипторы используются библиотеки io.h, stdio.h, fcntl.h, sys/stat.h.
а). Функция открытия файла имеет формат:
<fcтtl.h>
<io.h>
int open (Идентификатор-Файла, Вид-Доступа, Режим-Доступа);
const char *t int unsigned
Второй параметр определяет режим доступа к файлу. Он состоит из нескольких флагов, соединяемых логической операцией «или» - (|). Первый флаг определяет, как открывается файл, здесь используются следующие константы:
0_RDONLY только почтению,
0_WRONLY только по записи
0_RDWR по чтению-записи,
0_CREAT создание нового файла,
0_TRUNС
урезание существующего файла.
Второй флаг служит для определения режима работы с фалом – текстовый или двоичный:
0_BINARY
0_TEXT
Третий флаг определяет режим открытия файла:
S_IWRITE разрешение записи,
S_IREAD разрешение чтения,
S_IREAD/S_WRITE
б). Функция записи в файл имеет формат:
<io.h>
int write (Дексриптор, Имя-Переменной, Количество-Байт),
int void * unsigned long
Функция возвращает количество байт, записанной в файл информации.
в). Функция чтения из файла имеет формат:
<io.h>
int read (Дексриптор, Имя-Переменной, Количество-Байт),
int void
* unsigned long
Для работы с файлами дополнительно можно использовать функции close, tell и seek, которые аналогичны функциям работы через указатель на структуру FILE *, только в них отсутствует в качестве первого символа символ “f”.