Как проверить открыт ли файл си

Обновлено: 05.07.2024

До этого при вводе-выводе данных мы работали со стандартными потоками — клавиатурой и монитором. Теперь рассмотрим, как в языке C реализовано получение данных из файлов и запись их туда. Перед тем как выполнять эти операции, надо открыть файл и получить доступ к нему.

В языке программирования C указатель на файл имеет тип FILE и его объявление выглядит так:

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

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

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

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

Объявление функции fopen() содержится в заголовочном файле stdio.h, поэтому требуется его подключение. Также в stdio.h объявлен тип-структура FILE.

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

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

Чтение из текстового файла и запись в него

fscanf()

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

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

Допустим, у нас есть файл содержащий такое описание объектов:

Тогда, чтобы считать эти данные, мы можем написать такую программу:

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

fgets()

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

Такой вызов функции прочитает из файла, связанного с указателем myfile, одну строку текста полностью, если ее длина меньше 50 символов с учетом символа '\n', который функция также сохранит в массиве. Последним (50-ым) элементом массива str будет символ '\0', добавленный fgets() . Если строка окажется длиннее, то функция прочитает 49 символов и в конце запишет '\0'. В таком случае '\n' в считанной строке содержаться не будет.

В этой программе в отличие от предыдущей данные считываются строка за строкой в массив arr. Когда считывается следующая строка, предыдущая теряется. Функция fgets() возвращает NULL в случае, если не может прочитать следующую строку.

getc() или fgetc()

Функция getc() или fgetc() (работает и то и другое) позволяет получить из файла очередной один символ.

Приведенный в качестве примера код выводит данные из файла на экран.

Запись в текстовый файл

Также как и ввод, вывод в файл может быть различным.

  • Форматированный вывод. Функция fprintf ( файловый_указатель, строка_формата, переменные ) .
  • Посточный вывод. Функция fputs ( строка, файловый_указатель ) .
  • Посимвольный вывод. Функция fputc() или putc( символ, файловый_указатель ) .

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

Запись в каждую строку файла полей одной структуры:

Построчный вывод в файл ( fputs() , в отличие от puts() сама не помещает в конце строки '\n'):

Пример посимвольного вывода:

Чтение из двоичного файла и запись в него

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

При открытии файла для двоичного доступа, вторым параметром функции fopen() является строка "rb" или "wb".

Тема о работе с двоичными файлами достаточно сложная, для ее изучения требуется отдельный урок. Здесь будут отмечены только особенности функций чтения-записи в файл, который рассматривается как поток байтов.

Функции fread() и fwrite() принимают в качестве параметров:

  1. адрес области памяти, куда данные записываются или откуда считываются,
  2. размер одного данного какого-либо типа,
  3. количество считываемых данных указанного размера,
  4. файловый указатель.

Эти функции возвращают количество успешно прочитанных или записанных данных. Т.е. можно "заказать" считывание 50 элементов данных, а получить только 10. Ошибки при этом не возникнет.

Пример использования функций fread() и fwrite() :

Здесь осуществляется попытка чтения из первого файла 50-ти символов. В n сохраняется количество реально считанных символов. Значение n может быть равно 50 или меньше. Данные помещаются в строку. То же самое происходит со вторым файлом. Далее первая строка присоединяется ко второй, и данные сбрасываются в третий файл.

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

  • 1. Открыть файл, для того, чтобы к нему можно было обращаться. Соответственно, открывать можно для чтения, записи, чтения и записи, переписывания или записи в конец файла и т.п. Когда вы открываете файл, может также произойти куча ошибок – файла может не существовать, это может быть файл не того типа, у вас может не быть прав на работу с файлом и т.д. Всё это необходимо учитывать.
  • 2. Непосредственно работа с файлом - запись и чтение. Здесь также нужно помнить, что мы работаем не с памятью с произвольным доступом, а с буферизированным потоком, что добавляет свою специфику.
  • 3. Закрыть файл. Так как файл является внешним по отношению к программе ресурсом, то если его не закрыть, то он продолжит висеть в памяти, возможно, даже после закрытия программы (например, нельзя будет удалить открытый файл или внести изменения и т.п.). Кроме того, иногда необходимо не закрывать, а "переоткрывать" файл для того, чтобы, например, изменить режим доступа.

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

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

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

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

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

Функция fopen открывает файл. Она получает два аргумента – строку с адресом файла и строку с режимом доступа к файлу. Имя файла может быть как абсолютным, так и относительным. fopen возвращает указатель на объект FILE, с помощью которого далее можно осуществлять доступ к файлу.

Например, откроем файл и запишем в него Hello World

Функция fopen сама выделяет память под объект, очистка проводится функцией fclose. Закрывать файл обязательно, самостоятельно он не закроется.

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

Параметры доступа к файлу.
Тип Описание
r Чтение. Файл должен существовать.
w Запись нового файла. Если файл с таким именем уже существует, то его содержимое будет потеряно.
a Запись в конец файла. Операции позиционирования (fseek, fsetpos, frewind) игнорируются. Файл создаётся, если не существовал.
r+ Чтение и обновление. Можно как читать, так и писать. Файл должен существовать.
w+ Запись и обновление. Создаётся новый файл. Если файл с таким именем уже существует, то его содержимое будет потеряно. Можно как писать, так и читать.
a+ Запись в конец и обновление. Операции позиционирования работают только для чтения, для записи игнорируются. Если файл не существовал, то будет создан новый.

Если необходимо открыть файл в бинарном режиме, то в конец строки добавляется буква b, например “rb”, “wb”, “ab”, или, для смешанного режима “ab+”, “wb+”, “ab+”. Вместо b можно добавлять букву t, тогда файл будет открываться в текстовом режиме. Это зависит от реализации. В новом стандарте си (2011) буква x означает, что функция fopen должна завершиться с ошибкой, если файл уже существует. Дополним нашу старую программу: заново откроем файл и считаем, что мы туда записали.

Вместо функции fgets можно было использовать fscanf, но нужно помнить, что она может считать строку только до первого пробела.
fscanf(file, "%127s", buffer);

Также, вместо того, чтобы открывать и закрывать файл можно воспользоваться функцией freopen, которая «переоткрывает» файл с новыми правами доступа.

Функции fprintf и fscanf отличаются от printf и scanf только тем, что принимают в качестве первого аргумента указатель на FILE, в который они будут выводить или из которого они будут читать данные. Здесь стоит сразу же добавить, что функции printf и scanf могут быть без проблем заменены функциями fprintf и fscanf. В ОС (мы рассматриваем самые распространённые и адекватные операционные системы) существует три стандартных потока: стандартный поток вывода stdout, стандартный поток ввода stdin и стандартный поток вывода ошибок stderr. Они автоматически открываются во время запуска приложения и связаны с консолью. Пример

Ошибка открытия файла

Если вызов функции fopen прошёл неудачно, то она возвратит NULL. Ошибки во время работы с файлами встречаются достаточно часто, поэтому каждый раз, когда мы окрываем файл, необходимо проверять результат работы

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

В простых случаях можно действовать влоб, как в предыдущем куске кода. В более сложных случаях используются методы, подменяющиее RAII из С++: обёртки, или особенности компилятора (cleanup в GCC) и т.п.

Буферизация данных

  • 1) Если он заполнен
  • 2) Если поток закрывается
  • 3) Если мы явно указываем, что необходимо очистить буфер (здесь тоже есть исключения:)).
  • 4) Также очищается, если программа завершилась удачно. Вместе с этим закрываются и все файлы. В случае ошибки выполнения этого может не произойти.

Форсировать выгрузку буфера можно с помощью вызова функции fflush(File *). Рассмотрим два примера – с очисткой и без.

Раскомментируйте вызов fflush. Во время выполнения откройте текстовый файл и посмотрите на поведение.

Буфер файла можно назначить самостоятельно, задав свой размер. Делается это при помощи функции

которая принимает уже открытый FILE и указатель на новый буфер. Размер нового буфера должен быть не меньше чем BUFSIZ (к примеру, на текущей рабочей станции BUFSIZ равен 512 байт). Если передать в качестве буфера NULL, то поток станет небуферизированным. Можно также воспользоваться функцией

  • _IOFBF - полная буферизация. Данные записываются в файл, когда он заполняется. На считывание, буфер считается заполненным, когда запрашивается операция ввода и буфер пуст.
  • _IOLBF - линейная буферизация. Данные записываются в файл когда он заполняется, либо когда встречается символ новой строки. На считывание, буфер заполняется до символа новой строки, когда запрашивается операция ввода и буфер пуст.
  • _IONBF – без буферизации. В этом случае параметры size и buffer игнорируются.

Пример: зададим свой буфер и посмотрим, как осуществляется чтение из файла. Пусть файл короткий (что-нибудь, типа Hello, World!), и считываем мы его посимвольно

Видно, что данные уже находятся в буфере. Считывание посимвольно производится уже из буфера.

Функция int feof (FILE * stream); возвращает истину, если конец файла достигнут. Функцию удобно использовать, когда необходимо пройти весь файл от начала до конца. Пусть есть файл с текстовым содержимым text.txt. Считаем посимвольно файл и выведем на экран.

Всё бы ничего, только функция feof работает неправильно. Это связано с тем, что понятие "конец файла" не определено. При использовании feof часто возникает ошибка, когда последние считанные данные выводятся два раза. Это связано с тем, что данные записывается в буфер ввода, последнее считывание происходит с ошибкой и функция возвращает старое считанное значение.

Этот пример сработает с ошибкой (скорее всего) и выведет последний символ файла два раза.

Решение – не использовать feof. Например, хранить общее количество записей или использовать тот факт, что функции fscanf и пр. обычно возвращают число верно считанных и сопоставленных значений.

Примеры

1. В одном файле записаны два числа - размерности массива. Заполним второй файл массивом случайных чисел.

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

3. Пользователь вводит данные с консоли и они записываются в файл до тех пор, пока не будет нажата клавиша esc. Проверьте программу и посмотрите. как она себя ведёт в случае, если вы вводите backspace: что выводится в файл и что выводится на консоль.

4. В файле записаны целые числа. Найти максимальное из них. Воспользуемся тем, что функция fscanf возвращает число верно прочитанных и сопоставленных объектов. Каждый раз должно возвращаться число 1.

Другое решение считывать числа, пока не дойдём до конца файла.

5. В файле записаны слова: русское слово, табуляция, английское слово, в несколько рядов. Пользователь вводит английское слово, необходимо вывести русское.

Файл с переводом выглядит примерно так

солнце sun
карандаш pen
шариковая ручка pencil
дверь door
окно windows
стул chair
кресло armchair

и сохранён в кодировке cp866 (OEM 866). При этом важно: последняя пара cлов также заканчивается переводом строки.

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

6. Подсчитать количество строк в файле. Будем считывать файл посимвольно, считая количество символов '\n' до тех пор, пока не встретим символ EOF. EOF – это спецсимвол, который указывает на то, что ввод закончен и больше нет данных для чтения. Функция возвращает отрицательное значение в случае ошибки.
ЗАМЕЧАНИЕ: EOF имеет тип int, поэтому нужно использовать int для считывания символов. Кроме того, значение EOF не определено стандартом.

email

Всё ещё не понятно? – пиши вопросы на ящик

Открывает файл. Доступны более безопасные версии этих функций, которые выполняют дополнительные проверки параметров и возвращают коды ошибок. см. раздел fopen_s , _wfopen_s .

Синтаксис

Параметры

mode
Включенный тип доступа.

Возвращаемое значение

Каждая из этих функций возвращает указатель на открытый файл. Значение указателя null обозначает ошибку. Если параметр filename или mode имеет значение NULL или является пустой строкой, эти функции активируют обработчик недопустимых параметров, который описан в разделе Проверка параметров. Если выполнение может быть продолжено, эти функции возвращают значение NULL и задают значение еинвал.

Remarks

fopen Функция открывает файл, указанный параметром filename. По умолчанию строка с узким именем интерпретируется с помощью кодовой страницы ANSI ( CP_ACP ). в Windows классических приложениях это можно изменить на кодовую страницу OEM ( CP_OEMCP ) с помощью SetFileApisToOEM функции. С помощью функции можно AreFileApisANSI определить, интерпретируется ли имя файла с помощью ANSI или системной кодовой страницы OEM по умолчанию. _wfopen — Это версия с расширенными символами fopen ; аргументы для _wfopen представляют собой строки расширенных символов. В противном случае _wfopen fopen поведение идентично. Только использование _wfopen не влияет на закодированную кодировку, используемую в файловом потоке.

fopen принимает пути, допустимые в файловой системе в момент выполнения; fopen принимает пути UNC и пути, которые используют сопоставленные сетевые диски, если система, в которой выполняется код, имеет доступ к общей папке или подключенному диску во время выполнения. При создании путей для fopen Убедитесь, что диски, пути или сетевые папки будут доступны в среде выполнения. В пути в качестве разделителей каталогов можно использовать прямую (/) или обратную (\) косую черту.

Всегда проверяйте возвращаемое значение, чтобы узнать, равен ли указатель NULL, прежде чем выполнять какие-либо дальнейшие операции с файлом. При возникновении ошибки глобальная переменная errno задается и может использоваться для получения конкретных сведений об ошибке. Дополнительные сведения см. в статьях errno ,, _doserrno _sys_errlist и _sys_nerr .

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

Поддержка Юникода

fopen поддерживает файловые потоки в Юникоде. Чтобы открыть файл Юникода, передайте флаг CCS , который задает нужную кодировку fopen , следующим образом.

File * FP = fopen ("newfile.txt", "RT +, CCS =Encoding");

Допустимые значения кодировки : Unicode, UTF-8 и UTF-16LE.

Когда файл открывается в режиме Юникода, входные функции преобразуют данные, считываемые из файла, в данные UTF-16, хранящиеся в виде типа wchar_t . Функции, записывающие в файл, Открытый в режиме Юникода, предполагают буферы, содержащие данные UTF-16, хранящиеся в виде типа wchar_t . Если кодировка файла — UTF-8, при его записи данные UTF-16 преобразуются в UTF-8, а содержимое файла с кодировкой UTF-8 преобразуется в данные UTF-16 при его считывании. Попытка чтения или записи нечетного числа байтов в режиме Юникода приводит к ошибке проверки параметров . Для чтения или записи данных, хранимых в программе в кодировке UTF-8, используйте режим текстового или двоичного файла вместо режима Юникода. Вам необходимо реализовать все обязательные преобразования кодировки.

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

Обнаружение спецификации применяется только к файлам, открываемым в режиме Юникода (то есть путем передачи флага CCS ).

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

Кодирования, используемые на основе CCS-флага и метки BOM

Флаг CCS Нет метки BOM (или новый файл) BOM: UTF-8 BOM: UTF-16
UNICODE UTF-16LE UTF-8 UTF-16LE
UTF-8 UTF-8 UTF-8 UTF-16LE
UTF-16LE UTF-16LE UTF-8 UTF-16LE

В файлы, открытые для записи в режиме Юникода, метка BOM записывается автоматически.

Если mode имеет значение **a, CCS =Encoding * *, fopen сначала пытается открыть файл, используя доступ на чтение и запись. Если это завершается успешно, функция считывает метку BOM, чтобы определить кодировку для файла; если операция завершается сбоем, функция использует для файла кодировку по умолчанию. В любом случае снова fopen открывает файл, используя доступ только для записи. (Это относится только к режиму " a" , а не к режиму "a +" .)

Универсальное текстовое сопоставление функций

Подпрограмма TCHAR.H _UNICODE и _MBCS не определены _MBCS определено _UNICODE определено
_tfopen fopen fopen _wfopen

Режим символьной строки определяет тип доступа, запрашиваемый для файла, как показано ниже.

mode Доступ
Cерверный Открывает для чтения. Если файл не существует или не найден, fopen вызов завершается ошибкой.
Белая Открывает пустой файл для записи. Если указанный файл существует, его содержимое удаляется.
конкретного Открывается для записи в конце файла (добавление) без удаления маркера в конце файла (EOF) перед записью новых данных в файл. Создает файл, если он не существует.
"r +" Открывает для чтения и записи. Файл должен существовать.
"w +" Открывает пустой файл для чтения и записи. Если файл существует, его содержимое удаляется.
"a +" Открывается для чтения и добавления. Операция добавления включает удаления маркера EOF перед записью новых данных в файл. Маркер EOF не восстанавливается по окончании записи. Создает файл, если он не существует.

При открытии файла с помощью типа доступа "a" или типа доступа "a +" все операции записи выполняются в конце файла. Указатель файла может быть перемещен с помощью fseek или rewind , но всегда перемещается обратно в конец файла перед выполнением любой операции записи. Поэтому невозможно перезаписать существующие данные.

Режим "a" не УДАЛЯЕТ маркер EOF перед добавлением к файлу. После добавления команда MS-DOS TYPE отображает данные только до первоначального маркера EOF и не отображает данные, добавленные в файл. Перед добавлением в файл в режиме "a +" удаляется маркер EOF. После добавления команда TYPE MS-DOS отображает все данные в файле. Для добавления в потоковый файл, заканчивающийся маркером EOF CTRL + Z, требуется режим "a +" .

При указании типа доступа "r +", "w +" или "a +" разрешены операции чтения и записи (считается, что файл открыт для обновления). Однако при переходе от чтения к записи операция ввода должна получить маркер конца файла. Если маркер EOF отсутствует, необходимо воспользоваться промежуточным вызовом функции размещения файла. Функции позиционирования файлов: fsetpos , fseek и rewind . При переключении с записи на чтение необходимо использовать промежуточный вызов fflush функции либо в функцию позиционирования файла.

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

Модификатор режима Режим преобразования
t Откройте файл в текстовом (переведенном) режиме.
b Открыть в двоичном (непреобразованном) режиме; переводы, включающие символы возврата каретки и перевода строки, подавляются.

В текстовом режиме CTRL + Z интерпретируется как символ EOF на входе. В файлах, открытых для чтения и записи с помощью "a +", FOPEN проверяет наличие CTRL + Z в конце файла и удаляет его, если это возможно. Это делается потому, что использование fseek и ftell для перемещения в файле, заканчивающемся клавишей CTRL + Z, может привести fseek к неправильному поведению в конце файла.

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

Если t или b не задан в режиме, то режим преобразования по умолчанию определяется глобальной переменной _fmode . Если t или b является префиксом аргумента, функция завершается ошибкой и возвращает значение NULL.

Дополнительные сведения об использовании текстового и двоичного режимов в Юникоде, а также многобайтового потока ввода-вывода см. в статьях Text and Binary Mode File I/O и Ввод-вывод в поток в кодировке Юникод в текстовом и двоичном режиме.

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

Модификатор режима Поведение
x Вызывает сбой функции, если имя файла уже существует. Может использоваться только с описателями "w" или "w +".
c Включите флаг фиксации для связанного имени файла , чтобы содержимое файлового буфера записывалось непосредственно на диск при fflush _flushall вызове или.
n Сбросьте флаг фиксации для связанного файла с состоянием "без фиксации". Это значение по умолчанию. Оно также переопределяет глобальный флаг фиксации при соединении программы с COMMODE.OBJ. Значение по умолчанию глобального флага фиксации — без фиксации (no-commit), если только программа не связана явно с файлом COMMODE.OBJ (см. раздел Параметры ссылок).
N Указывает, что файл не наследуется дочерними процессами.
S Указывает, что кэширование оптимизировано для последовательного доступа с диска, но не ограничивается им.
R Указывает, что кэширование оптимизировано для случайного доступа с диска, но не ограничивается им.
T Определяет файл как временный. По возможности он не сбрасывается на диск.
D Определяет файл как временный. Он удаляется, если закрывается последний указатель файла.
CCS =кодирование Задает кодировку, используемую для этого файла (один из UTF-8, UTF-16LE или Unicode). Не указывайте никакое значение, если требуется использовать кодировку ANSI.

Допустимые символы для строки режима , используемой в fopen и _fdopen , соответствуют аргументам офлаг , которые используются в _open и _sopen , как показано ниже.

Символы в строке режима Эквивалентное значение офлаг для _ Open/ _ Сопен
конкретного _ O _ вронли | _ o _ append (обычно _ o _ вронли | _ O _ a | _ o _ append)
a + _ O _ РДВР | _ o _ append (обычно _ O _ РДВР | _ O _ append | _ o _ создание)
r _O _ рдонли
r + _O _ РДВР
w _ O _ вронли (обычно _ o _ вронли | _ o _ создание | _ O _ TRUNC)
w + _ O _ РДВР (обычно _ o _ РДВР | _ o _ создание | _ O _ TRUNC)
b _O _ binary
t _O _ текст
x _O _ без
c None
n None
S _O _ последовательный
R _O _ случайный
T _O _ шортливед
D _O _ временные
CCS = Юникод _O _ втекст
CCS = UTF-8 _O _ UTF8
CCS = UTF-16LE _O _ UTF16

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

Требования

Функция Обязательный заголовок
fopen <stdio.h>
_wfopen <stdio.h> либо <wchar.h>

_wfopen является расширением Microsoft. Дополнительные сведения о совместимости см. в разделе Совместимость.

Параметры режимов c, n, t, S, R, t и D являются расширениями Майкрософт для fopen и _fdopen и не должны использоваться, если требуется переносимость ANSI.

Пример 1

Следующая программа открывает два файла. Он использует fclose , чтобы закрыть первый файл и _fcloseall Закрыть все оставшиеся файлы.

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

Наиболее частые операции следующее:

    1. Методы проверки открыт ли файл is_open() и достигнут ли конец файла eof()
      1. Настройка форматированного вывода для >> с помощью width() и precision()
      1. Операции позиционирования tellg(), tellp() и seekg(), seekp()

      Это не все возможности, которые предоставляет библиотека fstream. Рассматривать все сейчас мы не будем, поскольку их круг применения достаточно узок. Познакомимся с вышеперечисленными. Начнем с класса чтения.

      Класс ifstream

      Открытие файла в конструкторе выглядит так:

      ifstream file ( "d:\\1\\файл.txt" ) ; // открываем файл в конструкторе

      Так мы просим открыть файл txt с именем файл.txt, который лежит в папке с названием 1, а папка находится на диске d.

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

      Так все отработает нормально и файл откроется:

      библиотека fstream, работа с файлами в с++, программирование для начинающих

      Второй вариант проверки с использованием метода is_open() :

      Метод is_open() вернет 1, если файл найден и успешно открыт. Иначе вернет 0 и сработает код прописанный в блоке else .

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

      Оператор считывания >>

      Так же как и в iostream считывание можно организовать оператором >> , который указывает в какую переменную будет произведено считывание:

      Считает вещественное, целое и строку. Считывание строки закончится, если появится пробел или конец строки. Стоит отметить, что оператор >> применяется к текстовым файлам. Считывание из бинарного файла производить лучше всего с помощью метода read().

      Кстати этот оператор достаточно удобен, если стоит задача разделить файл на слова:

      Методы getline() и get()

      Считывание целой строки до перевода каретки производится так же как и в iostream методом getline(). Причем рекомендуется использовать его переопределеную версию в виде функции, если считывается строка типа string:

      Если же читать нужно в массив символов char[], то либо get() либо getline() именно как методы:

      Принцип в общем тот же, что и в аналогах из iostream: Указывается в параметрах буфер (переменная, куда будет производиться чтение), или точнее указатель на блок памяти (если переменная объявлена статически: char buffer[255] к примеру, то пишется в параметры &buffer), указывается максимальное количество считываемого (в примере это n), дабы не произошло переполнение и выход за пределы буфера и по необходимости символ-разделитель, до которого будет считка (в примере это пробел). Надеюсь я не больно наступлю на хобот фанатикам Си, если сажу что эти две функции на 99% взаимозаменяемы, и на 95% могут быть заменены методом read() .

      Метод read()

      Похож на предыдущий пример?

      Метод close()

      Метод eof()

      Проверяет не достигнут ли конец файла. Т.е. можно ли из него продолжать чтение. Выше пример с считкой слов оператором >> как раз использует такую проверку.

      Метод seekg()

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

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