Если при открытии потока возникла ошибка диск заполнен при записи то указатель на поток приобретет

Обновлено: 06.07.2024

Файл в языке Си рассматривается как неструктурированная последовательность байтов. С этой точки зрения в языке программирования C файлом может быть как собственно файл на жестком диске, так и принтер, дисплей и другие подключаемые устройства ввода-вывода.

Как правило, взаимодействие между приложением и файлами производится посредством обмена блоков байт фиксированной длины (обычно длина представляет степень двойки - 256 или 512 байт).

При чтении из файла данные помещаются в буфер операционной системы, а затем побайтно передаются приложению.

При записи в файл данные накапливаются в буфере, а при заполнении буфера записываются на диск в виде единого блока байт.

Буферы представляют участки памяти, поэтому передача данных между приложением и буфером происходит довольно быстро в отличие от взаимодействия с физическими устройствами типа принтера.

Файл вместе с предоставляемыми средствами буферизации представляет поток .

Язык программирования Си содержит необходимый функционал для работы с файлами и устройствами ввода-вывода. Для применения его применения в программе необходимо подключить заголовочный файл stdio.h .

Открытие и закрытие потоков

Чтобы работать с потоком, его необходимо открыть. Для открытия потока применяется функция fopen() , которая имеет следующий прототип:

Первый параметр представляет имя открываемого файла, а второй задает режим открытия, от которого зависит, как файл может быть обработан.

Функция возвращает указатель на структуру, которая имеет тип FILE , определенный в том же файле stdio.h. Этот указатель идентифицирует поток в программе и через него мы сможем обращаться к открытому файлу.

При открытии поток связывается со структурой

Режимы открытия

Каждый режим задается в виде набора символов. В частности, мы можем использовать следующие режимы:

"w" : текстовый файл открывается для записи. Если файл ранее существовал, то он пересоздается и записывается заново

"r" : текстовый файл открывается для чтения

"a" : текстовый файл открывается для добавления в него новых данных. Если файл существовал ранее, то данные просто добавляются

"w+" : текстовый файл создается для записи/записи. Если файл ранее существовал, то при первой записи после открытия он пересоздается и записывается заново. А при последующих записях после открытия данные добавляются в него без перезаписи.

"r+" : текстовый файл открывается для чтения/записи. Запись допустима в любом месте файла, кроме конца файла, то есть недопустимо увеличение размеров файла.

"a+" : текстовый файл открывается или создается (при его отсутствии) для чтения/записи. В отличие от режима w+ файл при открытии не пересоздается заново, а в отличии от режима r+ можно записывать данные в конец файла

"wb" : бинарный файл открывается для записи

"rb" : бинарный файл открывается для чтения

"ab" : бинарный файл открывается для дозаписи

"w+b" : бинарный файл создается для записи/чтения

"r+b" : бинарный файл открывается для чтения/записи

"a+b" : бинарный файл открывается или создается (при его отсутствии) для чтения/дозаписи

Режимы позволяют разграничить доступ к файлу и открыть его только для чтения или только для записи или совместить оба варианта. Кроме того, на уровне режимов происходит разделение файлов на текстовые и бинарные. И программа будет обрабатывать файлы определенным образом, в зависимости какой режим будет выбран - для текстовых или бинарных файлов. Неправильно заданный режим может привести к некорректной интерпретации файла.

Закрытие файла

После завершения работы с файлом его следует закрыть. Для этого применяется функция fclose() :

Единственный параметр функции представляет ранее полученный при открытии файла указатель на структуру FILE, связанный с файлом.

Функция возвращает число: 0 - в случае успешного выполнения и встроенное значение EOF в случае ошибки.

Например, откроем и закроем файл "D:\data.txt":

Обработка ошибок

В процессе открытия или создания файла мы можем столкнуться с рядом ошибок, например, при открытии в режиме чтения не окажется подобного файла, недостаточно памяти и т.д. И в случае возникновения ошибки функция fopen() возвращает значение NULL . Мы можем обработать возникновение ошибки с помощью проверки результата функции:

Для вывода ошибки на консоль применяется встроенная функция perror() . И так как дальнейшие действия в программе в случае ошибки при открытии файла смысла не имеют, то с помощью вызова exit(0) завершаем работу приложения.

И если при попытке открытия файла по указанному пути его не окажется, то консоль выведет следующую ошибку:

Под вводом-выводом в программировании понимается процесс обмена информацией между оперативной памятью и внешними устройствами: клавиатурой, дисплеем, магнитными накопителя­ми и т. п. Ввод — это занесение информации с внешних устройств в оперативную память, а вывод — вынос информации из опера­тивной памяти на внешние устройства. Такие устройства, как дис­плей и принтер, предназначены только для вывода; клавиатура — устройство ввода. Магнитные накопители (диски, ленты) исполь­зуются как для ввода, так и для вывода.

Основным понятием, связанным с информацией на внешних устройствах ЭВМ, является понятие файла. Всякая операция вво­да-вывода трактуется как операция обмена с файлами: ввод — это чтение из файла в оперативную память; вывод — запись инфор­мации из оперативной памяти в файл. Поэтому вопрос об органи­зации в языке программирования ввода-вывода сводится к вопро­су об организации работы с файлами.

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

Аналогом понятия внутреннего файла в языках Си/Си++ яв­ляется понятие потока. Поток — это байтовая последовательность, передаваемая в про­цессе ввода-вывода.

Поток должен быть связан с каким-либо внешним устройством или файлом на диске. В терминологии Си это звучит так; поток должен быть направлен на какое-то устройство или файл.

Основные отличия файлов в Си состоят в следующем: здесь отсутствует понятие типа файла и, следовательно, фиксирован­ной структуры записи файла. Любой файл рассматривается как байтовая последовательность:


Стрелочкой обозначен указатель файла, определяющий теку­щий байт файла. EOF является стандартной константой — призна­ком конца файла.

Существуют стандартные потоки и потоки, объявляемые в про­грамме. Последние обычно связываются с файлами на диске, со­здаваемыми программистом. Стандартные потоки назначаются и открываются системой автоматически. С началом работы любой программы открываются 5 стандартных потоков, из которых ос­новными являются следующие:

o stdin — поток стандартного ввода (обычно связан с клавиатурой);

o stdout — поток стандартного вывода (обычно связан с дисплеем);

Кроме этого, открывается поток для стандартной печати и до­полнительный поток для последовательного порта.

Работа с файлами на диске. Работа с дисковым файлом начи­нается с объявления указателя на поток. Формат такого объяв­ления:

Слово file является стандартным именем структурного типа, объявленного в заголовочном файле stdio.h. В структуре file содержится информация, с помощью которой ведется работа с потоком, в частности: указатель на буфер, указатель (индикатор) текущей позиции в потоке и т.д.

Следующий шаг — открытие потока, которое производится с помощью стандартной функции fopen (). Эта функция возвраща­ет конкретное значение для указателя на поток и поэтому ее зна­чение присваивается объявленному ранее указателю. Соответству­ющий оператор имеет формат:

Имя_указателя=fореn (“имя_файла”, “режим_открытия”) ;

Параметры функции fopen () являются строками, которые мо­гут быть как константами, так и указателями на символьные мас­сивы. Например:

Здесь test .dat — это имя физического файла в текущем ката­логе диска, с которым теперь будет связан поток с указателем fр. Параметр режима r означает, что файл открыт для чтения. Что касается терминологии, то допустимо употреблять как выражение «открытие потока», так и выражение «открытие файла».

Существуют следующие режимы открытия потока и соответ­ствующие им параметры:

r открыть для чтения

w создать для записи

а открыть для добавления

r+ открыть для чтения и записи

w+ создать для чтения и записи

а+ открыть для добавления или

создать для чтения и записи

Поток может быть открыт либо для текстового, либо для дво­ичного (бинарного) режима обмена.

Понятие текстового файла: это последовательность символов, которая делится на строки специальными кодами — возврат ка­ретки (код 13) и перевод строки (код 10). Если файл открыт в текстовом режиме, то при чтении из такого файла комбинация символов «возврат каретки — перевод строки» преобразуется в один символ \n — переход к новой строке.

При записи в файл осуществляется обратное преобразование. При работе с двоичным файлом никаких преобразований симво­лов не происходит, т.е. информация переносится без всяких из­менений.

Указанные выше параметры режимов открывают текстовые файлы. Если требуется указать на двоичный файл, то к параметру добавляется буква b. Например: rb, или « b », или r +b. В некоторых компиляторах текстовый режим обмена обозначается буквой t, т.е. записывается a+t или rt.

Если при открытии потока по какой-либо причине возникла ошибка, то функция fopen() возвращает значение константы null. Эта константа также определена в файле stdio.h. Ошибка может возникнуть из-за отсутствия открываемого файла на диске, нехватки места в динамической памяти и т.п. Поэтому желатель­но контролировать правильность прохождения процедуры откры­тия файла. Рекомендуется следующий способ открытия:

if (fp=fopen("test.dat", "r")==NULL)

В случае ошибки программа завершит выполнение с закрыти­ем всех ранее открытых файлов.

Закрытие потока (файла) осуществляет функция fclose(), прототип которой имеет вид:

int fclose(FILE *fptr);

Здесь fptr обозначает формальное имя указателя на закрыва­емый поток. Функция возвращает ноль, если операция закрытия прошла успешно. Другая величина означает ошибку.

Запись и чтение символов. Запись символов в поток произво­дится функцией putc() с прототипом

int putc (int ch, FILE *fptr);

Если операция прошла успешно, то возвращается записанный символ. В случае ошибки возвращается константа EOF.

Считывание символа из потока, открытого для чтения, произ­водится функцией gets () с прототипом

int gets (FILE *fptr);

Функция возвращает значение считываемого из файла сим­вола. Если достигнут конец файла, то возвращается значение EOF. Заметим, что это происходит лишь в результате чтения кода EOF.

Исторически сложилось так, что gets() возвращает значение типа int. To же можно сказать и про аргумент ch в описании функции puts(). Используется же в обоих случаях только млад­ший байт. Поэтому обмен при обращении может происходить и с переменными типа char.

Пример 1. Составим программу записи в файл символьной пос­ледовательности, вводимой с клавиатуры. Пусть признаком завер­шения ввода будет символ *.

Особенностью С является отсутствие в этом языке структурированных файлов. Все файлы рассматриваются как не структурированная последовательность байтов. При таком подходе понятие файла распространяется и на различные устройства.

В С существуют средства ввода-вывода. Все операции ввода-вывода реализуются с помощью функций, которые находятся в библиотеке С. Библиотека С поддерживает три уровня ввода-вывода:

· ввод-вывод нижнего уровня;

· ввод-вывод для консоли и портов (зависит от ОС).

Поток – это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику.

Чтение данных из потока называется извлечением, вывод в поток – помещением, или включением.

При работе с потоком можно:

· Открывать и закрывать потоки (связывать указатели на поток с конкретными файлами);

· вводить и выводить строку, символ, форматированные данные, порцию данных произвольной длины;

· анализировать ошибки ввода-вывода и достижения конца файла;

· управлять буферизацией потока и размером буфера;

· получать и устанавливать указатель текущей позиции в файле.

Функции библиотеки ввода-вывода находятся в заголовочном файле <stdio.h>.

Прежде чем начать работать с потоком, его надо инициировать, т. е. открыть. При этом поток связывается со структурой предопределенного типа FILE, определение которой находится в библиотечном файле <stdio.h>. В структуре находится указатель на буфер, указатель на текущую позицию файла и т. п. При открытии потока, возвращается указатель на поток, т. е. на объект типа FILE.

fp= fopen( ”t.txt”, ”r”);

где fopen(<имя_файла>,<режим_открытия>) - функция для инициализации файла.

Существуют следующие режимы для открытия файла:

Режим Описание режима открытия файла
r Файл открывается для чтения, если файл не существует , то выдается ошибка при исполнении программы.
w Файл открывается для записи, если файл не существует, то он будет создан, если файл уже существует, то вся информация из него стирается.
a Файл открывается для добавления, если фай не существует, то он будет создан, если существует, то информация из него не стирается, можно выполнять запись в конец файла
r+ Файл открывается для чтения и записи, изменить размер файла нельзя, если файл не существует , то выдается ошибка при исполнении программы.
w+ Файл открывается для чтения и записи, если файл не существует, то он будет создан, если файл уже существует, то вся информация из него стирается.
a+ Файл открывается для чтения и записи, если фай не существует, то он будет создан, если существует, то информация из него не стирается, можно выполнять запись в конец файла

Поток можно открыть в текстовом (t) или двоичном (b) режиме. По умолчанию используется текстовый режим. В явном виде режим указывается следующим образом:

· ”r+b”или ”rb” - двоичный (бинарный) режим;

· ”r+t” или ”rt” – текстовый режим.

В файле stdio.h определена константа EOF, которая сообщает об окончании файла (отрицательное целое число).

При открытии потока могут возникать следующие ошибки:

· файл, связанный с потоком не найден (при чтении из файла);

· диск заполнен (при записи);

· диск защищен от записи (при записи) и т. п.

В этих случаях указатель на поток приобретет значение NULL (0). Указатель на поток, отличный от аварийного не равен 0.

Для вывода об ошибке при открытии потока используется стандартная библиотечная функция из файла <stdio.h>

void perror (const char*s);

if ((fp=fopen(”t.txt”, ”w”)==NULL)

perror(”\nошибка при открытии файла”);

После работы с файлом, его надо закрыть

Когда программа начинает выполняться, автоматически открываются несколько потоков, из которых основными являются:

· стандартный поток ввода (stdin);

· стандартный поток вывода (stdout);

· стандартный поток вывода об ошибках (stderr).

По умолчанию stdin ставится в соответствие клавиатура, а потокам stdout и stderr - монитор. Для ввода-вывода с помощью стандартных потоков используются функции:

· getchar()/putchar() – ввод-вывод отдельного символа;

· gets()/puts() – ввод-вывод строки;

· scanf()/printf() – форматированный ввод/вывод.

Аналогично работе со стандартными потоками выполняется ввод-вывод в потоки, связанные с файлами.

Для символьного ввода-вывода используются функции:




· int fgetc(FILE*fp), где fp – указатель на поток, из которого выполняется считывание. Функция возвращает очередной символ в форме int из потока fp. Если символ не может быть прочитан, то возвращается значение EOF.

· int fputc(int c, FILE*fp), где fp – указатель на поток, в который выполняется запись, c – переменная типа int, в которой содержится записываемый в поток символ. Функция возвращает записанный в поток fp символ в форме int . Если символ не может быть записан, то возвращается значение EOF.

Для построчного ввода-вывода используются следующие функции:

· char* fgets(char* s,int n,FILE* f), где char*s – адрес, по которому размещаются считанные байты, int n – количество считанных байтов, FILE* f – указатель на файл, из которого производится считывание.

Прием байтов заканчивается после передачи n-1 байтов или при получении управляющего символа ‘\n’. Управляющий символ тоже передается в принимающую строку. Строка в любом случае заканчивается ‘\0’. При успешном завершении работы функция возвращает указатель на прочитанную строку, при неуспешном – 0.

· int puts(char* s, FILE* f), где char*s – адрес, из которого берутся записываемые в файл байты, FILE* f – указатель на файл, в который производится запись.

Символ конца строки (‘\0’) в файл не записывается. Функция возвращает EOF, если при записи в файл произошла ошибка, при успешной записи возвращает неотрицательное число.

Для блокового ввода-вывода используются функции:

· int fread(void*ptr,int size, int n, FILE*f), где void*ptr – указатель на область памяти, в которой размещаются считанные из файла данные, int size – размер одного считываемого элемента, int n – количество считываемых элементов, FILE*f – указатель на файл, из которого производится считывание.

В случае успешного считывания функция возвращает количество считанных элементов, иначе – EOF.

· int fwrite(void*ptr,int size, int n, FILE*f), где void*ptr – указатель на область памяти, в которой размещаются считанные из файла данные, int size – размер одного записываемого элемента, int n – количество записываемых элементов, FILE*f – указатель на файл, в который производится запись.

В случае успешной записи функция возвращает количество записанных элементов, иначе – EOF.

В некоторых случаях информацию удобно записывать в файл без преобразования, т. е. в символьном виде пригодном для непосредственного отображения на экран. Для этого можно использовать функции форматированного ввода-вывода:

· int fprintf(FILE *f, const char*fmt,. . .) , где FILE*f – указатель на файл, в который производится запись, const char*fmt – форматная строка, . . . – список переменных, которые записываются в файл.

Функция возвращает число записанных символов.

· int fscanf(FILE *f, const char*fmt, par1,par2, . . .) , где FILE*f – указатель на файл, из которого производится чтение, const char*fmt – форматная строка, par1,par2,. . . – список переменных, в которые заносится информация из файла.

Функция возвращает число переменных, которым присвоено значение.

Средства прямого доступа дают возможность перемещать указатель текущей позиции в потоке на нужный байт. Для этого используется функция

· int fseek(FILE *f, long off, int org), где FILE *f - – указатель на файл, long off – позиция смещения, int org – начало отсчета.

Смещение задается выражение или переменной и может быть отрицательным, т. е. возможно перемещение как в прямом, так и в обратном направлениях. Начало отсчета задается одной из определенных в файле <stdio.h> констант:

SEEK_SET ==0 – начало файла;

SEEK_CUR==1 – текущая позиция;

SEEK_END ==2 – конец файла.

Функция возвращает 0, если перемещение в потоке выполнено успешно, иначе возвращает ненулевое значение.

Обработка элементов файла

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

void del(char *filename)

FILE *f;//исходный файл

//открыть исходный файл для чтения

//открыть вспомогательный файл для записи

student a;//буфер для чтения данных из файла

//считываем данные из исходного файла в буфер

for(long i=0; fread(&a,sizeof(student),1,f);i++)

if(i!=x)//если номер записи не равен х

//записываем данные из буфера во временный файл

fclose(f);//закрываем исходный файл

fclose(temp); //закрываем временный файл

remove(filename);//удаляем исходный файл

rename(”temp”, filename);//переименовываем временный файл

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

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

Для добавления элементов конец файла достаточно открыть его в режиме “a” или “a+” (для добавления) и записать новые данные в конец файла.

f=fopen(filename,”ab”);//открыть файл для добавления

cout<<"\nHow many records would you add to file?";

fwrite(&a,sizeof(student),1,f);//записать в файл

2.3. Потоковый ввод-вывод в стиле С++

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

По направлению обмена потоки можно разделить на

· входные (данные вводятся в память),

· выходные (данные выводятся из памяти),

· двунаправленные (допускаю­щие как извлечение, так и включение).

По виду устройств, с которыми работает поток, потоки можно разделить на стан­дартные, файловые и строковые:

· стандартные потоки предназначены для передачи данных от клавиатуры и на экран дисплея,

· файловые потоки для обмена информацией с файлами на внеш­них носителях данных (например, на магнитном диске),

· строковые потоки — для работы с массивами символов в оперативной памяти.

Для работы со стандартными потоками библиотека C++ содержит библиотеку <iostream.h>. При этом в программе автоматически становятся доступными объекты:

· cin - объект, соответствует стандартному потоку ввода,

· cout - объект, соответствует стандартному потоку вывода.

Оба эти потока являются буферизированными.

Форматированный ввод/вывод реализуется через две операции:

· >> - чтение из потока.

Использование файлов в программе предполагает следующие операции:

· открытие потока и связывание его с файлом;

Для работы со файловыми потоками библиотека C++ содержит библиотеки:

· <ifstream.h> - для работы с входными потоками,

· <ofstream.h> - для работы с выходными потоками

· <fstream.h> - для работы с двунаправленными потоками.

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

Для создания файлового потока используются специальные методы –конструкторы, которые создают поток соответствующего класса, от­крывают файл с указанным именем и связывают файл с потоком:

· ifstream(const char *name, int mode = ios::in);//входной поток

· ofstream(const char *name, int mode = ios::out | ios::trunc);//выходной поток

· fstreamCconst char *name, int mode = ios::in | ios::out);//двунаправленный поток

Вторым параметром является режим открытия файла. Вместо значения по умолчанию можно указать одно из следующих значений, определенных в классе ios.

ios::in открыть файл для чтения;
ios::out открыть файл для записи;
ios::ate установить указатель на конец файла, читать нельзя, можно только записывать данные в конец файла;
ios::app открыть файл для добавления;
ios::trunc если файл существует, то создать новый;
ios::binary открыть в двоичном режиме;
ios::nocreate если файл не существует, выдать ошибку, новый файл не открывать
ios::noreplace если файл существует, выдать ошибку, существующий файл не открывать;

Открыть файл в программе можно с использованием либо конструкторов, либо метода open, имеющего такие же параметры, как и в соответствующем конструк­торе.

fstream f; //создает файловый поток f

//открывается файл, который связывается с потоком

// создает и открывает для чтения файловый поток f

fstream f (”..\\f.dat”,ios::in);

После того как файловый поток открыт, работать с ним можно также как и со стандартными потоками cin и cout. При чтении данных из входного файла надо контролировать, был ли достигнут конец файла после очередной операции вывода. Это можно делать с помощью метода eof().

Если в процессе работы возникнет ошибочная ситуация, то потоковый объект принимает значение равное 0.

Когда программа покидает область видимости потокового объекта, то он уничтожается, при этом перестает существовать связь между потоковым объектом и физическим файлом, а сам файл закрывается. Если файл требуется закрыть раньше, то используется метод close().

//создание файла из элементов типа person

person *mas;//динамический массив

fstream f("f.dat",ios::out);//двунаправленный файловый поток

mas=new person[n];//создаем динамический массив

//ввод одного элемента типа person из стандартного потока cin

//запись элементов массива в файловый поток

//чтение элементов из файла

f.open("f.dat",ios::in);//открываем поток для чтения

/*читаем элементы типа person из файлового потока f в переменную p*/

// если достигнут конец файла, выходим из цикла

Постановка задачи

  1. Используя ввод-вывод в стиле С создать файл и записать в него структурированные данные.
  2. Вывести созданный файл на экран.
  3. Удалить из файла данные в соответствии с вариантом.
  4. Добавить в файл данные в соответствии с вариантом.
  5. Вывести измененный файл на экран.
  6. Используя ввод-вывод в стиле С++ создать файл и записать в него структурированные данные.
  7. Вывести созданный файл на экран.
  8. Удалить из файла данные в соответствии с вариантом.
  9. Добавить в файл данные в соответствии с вариантом.
  10. Вывести измененный файл на экран.

Содержание отчета

  1. Постановка задачи (общая и для конкретного варианта).
  2. Определения функций для реализации поставленных задач.
  3. Определение функции main().
  4. Содержимое исходного файла
  5. Содержимое модифицированного файла.

Список литературы

1. Ашарина И.В. Основы программирования на языках С и С++.-М.: Горячая линия-Телеком, 2012.-207 с.

2. Боровский А.Н. С++ и Borland C++Builder. Самоучитель.-СПб.:Питер, 2011.-256 с.

3. Вендеров А.М. Проектирование программного обеспечения экономических информационных систем: Учебник.-2-е изд., перераб. и доп. – М.:Финансы и статистика, 2009.-544с.:ил.

4. Грэхем И. Объектно-ориентированные методы. Принципы и практика. 3-е издание.:Пер. с англ.-М.:Издательский дом "Вильямс", 2010.-880с.:ил.-Парал.тит.англ.

5. Иванова Г.С., Ничушкина Т.Н., Пугачев Е.К. Объектно-ориентированное программирование: Учебник для вузов.-2-е изд., перераб и доп/ Под ред. Г.С.Ивановой.-М.:Изд-во МГТУ им. Н.Э.Баумана, 2009.-368 с.

6. Крячков А.В. Программирование на С и С++. Практикум [Текст]: учебное пособие для вузов/ А.В. Крячков, И.В. Сухинина и др. – СПб.: Питер, 2011. – 358 с.

7. Пол А. Объектно-ориентированное программирование на С++, 2-е изд./Пер. с англ. - СПб.; "Невский диалект" - "Издательство БИНОМ", 2008 г. - 462 с.

8. Страуструп Б. Язык программирования С++ [Текст]: учебник/ Б. Страуструп. – СПб: Питер, 2009. – 991 с.

9. Фридман А.Л. Основы объектно-ориентированного программирования на языке С++. Изд.2-е перераб. и доп. - М.: Горячая линия - Телеком, 2011. - 232с.

Цель лекции: изучить понятия, характеристику и классификацию файлов и стандартных функций по работе с файлами, научиться решать задачи с использованием стандартных функций по работе с файлами на языке C++.

Файл – это именованная область внешней памяти, в которой хранится логически завершенный объем данных. Файл имеет следующие характерные особенности:

  • имеет имя на диске, что дает возможность программам идентифицировать и работать с несколькими файлами;
  • длина файла ограничивается только емкостью диска.

Часто бывает необходимо ввести некоторые данные из файла или вывести результаты в файл . Например, бывает необходимо обрабатывать массивы, которые слишком велики, чтобы полностью разместиться в памяти.

Файлы делятся на текстовые и двоичные.

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

Двоичный файл – файл , данные которого представлены в бинарном виде. При записи в двоичный файл символы и числа записываются в виде последовательности байт (в своем внутреннем двоичном представлении в памяти компьютера).

Особенностью языка С++ является отсутствие в нем структурированных файлов. Все файлы рассматриваются как неструктурированная последовательность байтов. При таком подходе понятие файла распространяется и на различные устройства.

В С++ существуют специальные средства ввода-вывода данных. Все операции ввода-вывода реализуются с помощью функций, которые находятся в библиотеке С++. Библиотека С++ поддерживает три уровня ввода-вывода:

  • потоковый ввод-вывод;
  • ввод-вывод нижнего уровня;
  • ввод-вывод для консоли и портов (зависит от ОС).

Поток – это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику.

Функции библиотеки ввода-вывода языка С++, поддерживающие обмен данными с файлами на уровне потока, позволяют обрабатывать данные различных размеров и форматов, обеспечивая при этом буферизованный ввод и вывод . Таким образом, поток представляет собой этот файл вместе с предоставленными средствами буферизации.

Чтение данных из потока называется извлечением, вывод в поток – помещением (включением).


Рис. 19.1. Буферизация данных при работе с потоками

При работе с потоком можно:

  • открывать и закрывать потоки (связывать указатели на поток с конкретными файлами);
  • вводить и выводить строку, символ, форматированные данные, порцию данных произвольной длины;
  • анализировать ошибки ввода-вывода и достижения конца файла;
  • управлять буферизацией потока и размером буфера;
  • получать и устанавливать указатель текущей позиции в файле.

Когда программа начинает выполняться, автоматически открываются пять потоков, из которых основными являются:

По умолчанию стандартному потоку ввода stdin ставится в соответствие клавиатура, а потокам stdout и stderr соответствует экран монитора.

В С++ операции с файлами можно осуществлять в двух режимах: форматированном и потоковом.

Рассмотрим основные функции для работы с файлами в форматированном режиме.

Функция открытия файла

Для работы с файлом в языке C++ необходима ссылка на файл . Для определения такой ссылки существует структура FILE , описанная в файле stdio.h . Данная структура содержит все необходимые поля для управления файлами, например: текущий указатель буфера, текущий счетчик байтов, базовый адрес буфера ввода-вывода, номер файла.

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

Для открытия файла существует функция fopen , которая инициализирует файл .

где fp – указатель на поток (файловый указатель );

ИмяФайла – указатель на строку символов, представляющую собой допустимое имя файла , в которое может входить спецификация файла (включает обозначение логического устройства, путь к файлу и собственно имя файла );

РежимОткрытия – указатель на строку режима открытия файла.

Существуют несколько режимов открытия файлов.

Поток можно открыть в текстовом ( t ) или двоичном ( b ) режиме. По умолчанию используется текстовый режим . В явном виде режим указывается следующим образом:

"r+b" или "rb" – двоичный (бинарный) режим;

"r+t" или "rt" – текстовый режим .

В файле stdio.h определена константа EOF , которая сообщает об окончании файла (отрицательное целое число ).

При открытии файла могут возникать следующие ошибки:

  • файл, связанный с потоком не найден (при чтении из файла);
  • диск заполнен (при записи);
  • диск защищен от записи (при записи) и т. п.

В этих случаях указатель на поток приобретет значение NULL (0) . Указатель на поток , отличный от аварийного, не бывает равен NULL .

Пример 1. Обнаружение и вывод ошибки при открытии файла.

Перед началом выполнения операций с файлами целесообразно получить подтверждение, что функция fopen () выполнилась успешно.

миниатюра Ошибка формата потока

Почему возникает ошибка формата потока 1С Предприятие 8.3

Что бы выяснить причины появления ошибки формата потока 1С 8.3 необходимо рассмотреть область данных 1С платформы. Тут хотелось бы отметить, что платформа 1С во время работы использует:

  • жесткий диск, на который во время работы платформы 1С сохраняются временные файлы настроек, логи, сервисная и пользовательская информация;
  • сеть (в случае сетевой работы), по средствам которой происходит обмен пакетами данных с другими компьютерами или серверами сети (в случае клиент-серверного варианта работы 1С Предприятие).

Причем, платформа 1С Предприятие использует указанные ресурсы постоянно.

Монитор ресурсов при работе 1С Предприятие 8

А теперь представьте, что произошел скачек электричества, поэтому часть сетевого пакета исказилась и была записана в некорректной форме или отключили электричество и данные, которые писались в кеш 1С записались частично, что в этом случае произойдет?

Первым делом необходимо сделать копию информационной базы 1С на случай порчи рабочей базы при её исправлении.

Если вы работая в файловой версии 1С Предприятие , стали жертвой этой напасти, то хочу предложить способ от её избавления, работающий в 78% случаев.

  • Для этого необходимо зайти в каталог, где хранится база данных 1С Предприятие 8.3 и удалить все файлы и папки, КРОМЕ ФАЙЛА ДАННЫХ 1Cv8.CD . Операция требует сноровки, поэтому будьте осторожны, не переборщите с удалением! 🙂

Ошибка формата потока 1С Предприятие 8.3 - удалить файлы из папки с базой данных

  • Если предложенный способ не помог, то для исправления файловых баз в 1С Предприятие 8.3 предусмотрена утилита chdbfl.exe. Проверьте структуру вашей базы, воспользовавшись этой утилитой.

Ошибка формата потока 1С 8.3 не исчезла? Плохо! Читаем дальше.

Стандартные шаги по исправлению ошибки формата потока 1С Предприятие 8.3

Если указанные выше рекомендации не помогли в исправлении ошибки формата потока 1С или если у вас клиент-серверная база данных 1С, то следующими шагами исправления будут стандартные операции, возникающие при любых ошибках:

На эти темы были написаны подробные публикации, поэтому тут мне добавить нечего. Читайте статьи и делайте всё в точности по написанному.

  • выгрузите вашу базу с файл *.dt, создайте пустую базу 1С и загрузите в неё выгруженный до этого файл *.dt. В выполнении этой операции вам поможет статья про резервное копирование базы 1С Предприятие 8.3.

Есть ещё пара способов с хакерским подходом:

Надеюсь, что ничего не забыл. Если вдруг всплывет в памяти что-то ещё, то обязательно дополню публикацию.

Всем читателям отличного настроения! Пусть ошибка формата потока вас обходит стороной. 😉

Интересная статья. Раньше мне подобная ситуация казалась безвыходной, хотя рабочие базы она обычно не затрагивала. Ещё стоит добавить, что желательно регулярно делать бекап базы, чтобы таких ошибок можно было избежать.

Ценное замечание! Добавил в публикацию упоминание о необходимости создания резервной копии.

спасибо помогло. вариант и РИБ

Пожалуйста! Всегда рад, когда публикации приносят пользу.

Мне помогло в итоге файл базы скопировать в другую базу и прописать ее заново. Спасибо!

Спасибо помогло в варианте очистить файл от всех записей в таблице «configsave»

Спасибо, помог вариант с удалением!

Интересная и полезная статься. Спасибо

Доброго дня.
Файловый вариант базы данных.
Уже и базу удалила и удалила 1с предприятие, сменила пользователя windows, почистила кэш.
Тестировала и исправляла базу данных, всё равно ошибка сохраняется.
делала:
брала рабочую конфигурацию, в неё загружала файл dt и потом пробовала зайти в 1с- ошибка сохраняется.
Выгрузка в dt идёт, конфигуратор открывается, при загрузке конфигурации из файла- база вылетает
Tool_1CD к сожалению для 8.3 не имеется у меня.

Может у кого-нибудь есть ещё какие-нибудь решения??
Благодарю за помощь.

Попробуйте загрузить на другом компьютере, если база заработает, то дело в вашей системе, если нет, то дело в загрузке.
Пробуйте:
1) Очистить кеш
2) Создать пустую базу в новой папке
3) Загрузить dt
4) Сделать тестирование и исправление

Огромное Вам спасибо! Помогла просто выгрузка-загрузка

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

Помогло удаление временных файлов где установлена платформа по адресу пользователи/ апдата /1с/ папка со всякими закпрючками

Подскажите, как быть с SQL-серверной базой данных, если не запускается ни конфигуратор, ни Предприятие с ошибкой формата потока у всех пользователей. Ошибка возникла во время динамического обновления конфигурации.

Тут может быть масса причин, этой ситуацией надо заниматься.
Попробуйте стандартные процедуры: сделать тестирование и исправление бд, выгрузить dt и загрузить в новую базу.

Добрый вечер, было отключение света, всё уже перепробовала, ничего не помогает, помогите открыть злосчастную бд, пожалуйста

Спасибо тебе Добрый человек! Спасли 🙂 Дай бог здоровья!

Дополнительная помощь для тех, кто работает в Windows 7 и выше: ОС делает теневые копии файлов (если не отключена). Таким образом файловую базу (файлы) можно восстановить из теневой копии. Мне помог только этот вариант, остальные не помогли. У меня бух прервал обновление базы.

Спасибо. Мне помогла очистка кэша

чистка кеша помогла, спасибо! 🙂

Способ №1 (он же очистка кэша 1С) : Удалить базу из списка. Добавить базу в список. Все.

Вы все случаи описываете в файловой системе.
Но кто вообще пользуется файловыми базами? Магазин с 3 сотрудниками?
У нас база на sql и ни один из способов при такой ошибке нам не помогает?

Добавить комментарий Отменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Читайте также: