fopen, _wfopen

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

FILE *fopen(     const char *filename,    const char *mode  ); FILE *_wfopen(     const wchar_t *filename,    const wchar_t *mode  );

Параметры

  • filename
    Имя файла.

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

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

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

Для получения дополнительной информации см. errno, _doserrno, _sys_errlist, and _sys_nerr.

Заметки

Функция fopen открывает файл, заданный filename. _wfopen — это двухбайтовая версия fopen; аргументы для _wfopen представляют собой двухбайтовые строки. В противном случае поведение _wfopen и fopen идентично. Использование исключительно _wfopen не влияет на набор закодированных символов, используемый в файловом потоке.

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

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

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

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

fopen(&fp, "newfile.txt", "rt+, ccs=encoding");

Допустимые значения 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), если она присутствует в файле, определяет кодирование. Кодирование BOM имеет приоритет над кодированием, заданным флагом ccs. Кодирование ccs используется, только если метка BOM отсутствует или речь идет о новом файле.

Примечание

Обнаружение метки BOM применяется только к файлам, которые будут открываться в режиме Юникода (т е путем передачи флага 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 указывает тип доступа, который запрошен для файла, следующим образом.

  • "r"
    Открывает для чтения. Если файл не существует или его невозможно найти, вызов fopen завершается ошибкой.

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

  • "a"
    Открывается для записи в конце файла (добавление) без удаления маркера в конце файла (EOF) перед записью новых данных в файл. Создает файл, если он не существует.

  • "r+"
    Открывает для чтения и записи. Файл должен существовать.

  • "w+"
    Открывает пустой файл для чтения и записи. Если файл существует, его содержимое удаляется.

  • "a+"
    Открывается для чтения и добавления. Операция добавления включает удаления маркера EOF перед записью новых данных в файл. Маркер EOF не восстанавливается по окончании записи. Создает файл, если он не существует.

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

Режим "a" не удаляет маркер EOF, прежде чем будет выполнено добавление в файл. После добавления команда MS-DOS TYPE отображает данные только до первоначального маркера EOF и не отображает данные, добавленные в файл. Перед добавлением в файл режим "a+" удаляет маркер EOF. После добавления команда TYPE MS-DOS отображает все данные в файле. Режим "a+" необходим для добавления в потоковый файл, завершаемый маркером конца файла CTRL+Z.

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

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

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

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

  • b
    При открытии в двоичном (непреобразованном) режиме преобразования, включающие символы возврата каретки и перевода строки, подавляются.

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

Дополнительные сведения об использовании текстового и двоичного режимов в Юникоде и при многобайтовом потоке ввода-вывода см. в разделах Файловый ввод-вывод в текстовом и двоичном режиме и Ввод-вывод в поток в кодировке Юникод в текстовом и двоичном режиме.

  • c
    Включите флажок фиксации для связанного объекта filename, чтобы содержимое файлового буфера записывалось непосредственно на диск при вызове fflush или _flushall.

  • n
    Сбросьте флажок фиксации для связанного объекта filename, задайте для него значение "без фиксации". Это значение по умолчанию. Оно также переопределяет глобальный флаг фиксации при соединении программы с COMMODE.OBJ. Значение по умолчанию глобального флага фиксации — "без фиксации", если только программа не связана явно с файлом COMMODE.OBJ (см. Параметры ссылок).

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

  • S
    Указывает, что кэширование оптимизировано для последовательного доступа с диска, но не ограничивается им.

  • R
    Указывает, что кэширование оптимизировано для случайного доступа с диска, но не ограничивается им.

  • T
    Определяет файл как временный. По возможности он не сбрасывается на диск.

  • D
    Определяет файл как временный. Он удаляется, если закрывается последний указатель файла.

  • ccs=ENCODING
    Задает набор кодированных символов, которые требуется использовать (UTF-8, UTF-16LE или UNICODE) для этого файла. Не указывайте никакое значение, если требуется использовать кодировку ANSI.

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

Символы в строке режима

Эквивалентное значение oflag для _open или _sopen

a

_O_WRONLY | _O_APPEND (обычно _O_WRONLY | _O_CREAT | _O_APPEND)

a+

_O_RDWR | _O_APPEND (обычно _O_RDWR | _O_APPEND | _O_CREAT )

r

_O_RDONLY

r+

_O_RDWR

w

_O_WRONLY (обычно _O_WRONLY | _O_CREAT | _O_TRUNC)

w+

_O_RDWR (обычно _O_RDWR | _O_CREAT | _O_TRUNC)

b

_O_BINARY

t

_O_TEXT

c

Нет

n

Нет

S

_O_SEQUENTIAL

R

_O_RANDOM

T

_O_SHORTLIVED

D

_O_TEMPORARY

ccs=UNICODE

_O_WTEXT

ccs=UTF-8

_O_UTF8

ccs=UTF-16LE

_O_UTF16

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

Требования

Функция

Обязательный заголовок

fopen

<stdio.h>

_wfopen

<stdio.h> или <wchar.h>

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

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

Пример

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

// crt_fopen.c
// compile with: /W3
// This program opens two files. It uses
// fclose to close the first file and
// _fcloseall to close all remaining files.

#include <stdio.h>

FILE *stream, *stream2;

int main( void )
{
   int numclosed;

   // Open for read (will fail if file "crt_fopen.c" does not exist)
   if( (stream  = fopen( "crt_fopen.c", "r" )) == NULL ) // C4996
   // Note: fopen is deprecated; consider using fopen_s instead
      printf( "The file 'crt_fopen.c' was not opened\n" );
   else
      printf( "The file 'crt_fopen.c' was opened\n" );

   // Open for write 
   if( (stream2 = fopen( "data2", "w+" )) == NULL ) // C4996
      printf( "The file 'data2' was not opened\n" );
   else
      printf( "The file 'data2' was opened\n" );

   // Close stream if it is not NULL 
   if( stream)
   {
      if ( fclose( stream ) )
      {
         printf( "The file 'crt_fopen.c' was not closed\n" );
      }
   }

   // All other files are closed: 
   numclosed = _fcloseall( );
   printf( "Number of files closed by _fcloseall: %u\n", numclosed );
}
  

Следующая программа создает файл (или перезаписывает его, если имеется) в текстовом режиме с кодировкой Юникода. Затем она записывает две строки в файл и закрывает его. В результате получается файл с именем _wfopen_test.xml, который содержит данные из раздела вывода.

// crt__wfopen.c
// compile with: /W3
// This program creates a file (or overwrites one if
// it exists), in text mode using Unicode encoding.
// It then writes two strings into the file
// and then closes the file.
 
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>

#define BUFFER_SIZE 50

int main(int argc, char** argv)
{
wchar_t str[BUFFER_SIZE];
size_t  strSize;
FILE*   fileHandle;

    // Create an the xml file in text and Unicode encoding mode.
    if ((fileHandle = _wfopen( L"_wfopen_test.xml",L"wt+,ccs=UNICODE")) == NULL) // C4996
    // Note: _wfopen is deprecated; consider using _wfopen_s instead
    {
        wprintf(L"_wfopen failed!\n");
        return(0);
    }

    // Write a string into the file.
    wcscpy_s(str, sizeof(str)/sizeof(wchar_t), L"<xmlTag>\n");
    strSize = wcslen(str);
    if (fwrite(str, sizeof(wchar_t), strSize, fileHandle) != strSize)
    {
        wprintf(L"fwrite failed!\n");
    }

    // Write a string into the file.
    wcscpy_s(str, sizeof(str)/sizeof(wchar_t), L"</xmlTag>");
    strSize = wcslen(str);
    if (fwrite(str, sizeof(wchar_t), strSize, fileHandle) != strSize)
    {
        wprintf(L"fwrite failed!\n");
    }

    // Close the file.
    if (fclose(fileHandle))
    {
        wprintf(L"fclose failed!\n");
    }
    return 0;
}

Эквивалент в .NET Framework

См. также

Ссылки

Потоковый ввод-вывод

Интерпретация последовательностей в многобайтной кодировке

fclose, _fcloseall

_fdopen, _wfdopen

ferror

_fileno

freopen, _wfreopen

_open, _wopen

_setmode

_sopen, _wsopen