Поделиться через


fopen, _wfopen

Открывает файл. Доступны более безопасные версии этих функций, которые выполняют больше проверки параметров и возвращают коды ошибок; see 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 или есть NULL или mode пустая строка, эти функции активируют недопустимый обработчик параметров, который описан в разделе "Проверка параметров". Если продолжение выполнения разрешено, эти функции возвращают NULL и устанавливают для errno значение EINVAL.

Дополнительные сведения см. в разделе errno, _doserrno, _sys_errlist, и _sys_nerr.

Замечания

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

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

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

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

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

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

FILE *fp = fopen("newfile.txt", "rt+, ccs=UTF-8");

Допустимые значения для ccs кодирования: UNICODEи UTF-8UTF-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 значение имеет некоторое encoding значение, fopen сначала пытается a, ccs=encoding открыть файл с помощью доступа на чтение и запись. Если это действие выполнено успешно, функция считывает BOM, чтобы определить кодировку для файла. Если он завершается ошибкой, функция использует кодировку по умолчанию для файла. В любом случае fopen повторно открывает файл с помощью доступа только для записи. (Это поведение применяется только к режиму "a" , а не к режиму "a+" .)

Сопоставления подпрограмм универсального текста

TCHAR.H рутина _UNICODE и _MBCS не определен _MBCS Определенные _UNICODE Определенные
_tfopen fopen fopen _wfopen

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

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 EOF.

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

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

mode модификатор Режим перевода
t Откройте файл в текстовом (переведенном) режиме. Сочетания канала возврата каретки (CR-LF) превратятся в однострочные каналы (LF) для входных данных и символов LF превратятся в сочетания CR-LF для выходных данных. Кроме того, при вводе символ CTRL+Z интерпретируется как символ конца файла.
b Откройте в двоичном (нетрансляционном) режиме; переводы, включающие символы канала каретки и строки, подавляются.

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

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

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

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

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

mode модификатор Поведение
x Принудительно принудить функцию завершиться ошибкой, если filename она уже существует. Можно использовать только с описателями w или w+.
c Включите флажок фиксации для связанного объекта filename , чтобы содержимое файлового буфера записывалось непосредственно на диск при вызове fflush или _flushall .
n Сброс флага фиксации для связанного filename с "no-commit". Этот флаг по умолчанию. Оно также переопределяет глобальный флаг фиксации при соединении программы с COMMODE.OBJ. Флаг глобальной фиксации по умолчанию — "без фиксации", если вы явно не связываете программу с COMMODE. OBJ (см . параметры ссылки).
N Указывает, что файл не наследуется дочерними процессами.
S Указывает, что кэширование оптимизировано для последовательного доступа с диска, но не ограничивается им.
R Указывает, что кэширование оптимизировано для случайного доступа с диска, но не ограничивается им.
T Указывает файл, который не записывается на диск, если это не требуется.
D Указывает временный файл, который удаляется при закрытии последнего указателя файла.
ccs=encoding Задает закодированный набор символов, используемый (один из UTF-8, UTF-16LEили UNICODE) для этого файла. Не указывайте никакое значение, если требуется использовать кодировку ANSI. Этот флаг отделяется от флагов, предшествующих запятой (,). Например: FILE *f = fopen("newfile.txt", "rt+, ccs=UTF-8");

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

Символы в строке mode Эквивалентное значение 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 (переведено)
x _O_EXCL
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 в качестве параметра.

Относительно T и D:

  • T избегает записи файла на диск до тех пор, пока не требуется давление на память. Дополнительные сведения см. в разделе FILE_ATTRIBUTE_TEMPORARY "Константы атрибутов файла", а также в этой записи блога Только временный.
  • D указывает обычный файл, записанный на диск. Разница заключается в том, что он автоматически удаляется при закрытии. Вы можете объединить оба TD семантики.

<a0/>, n, tTSRи D mode параметры — это расширения Майкрософт для fopen и _wfopen не должны использоваться, если требуется переносимость ANSI.

Требования

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

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

cДля Rnmode TSD tи не следует использовать расширения fopen _fdopen Майкрософт , и параметры, в которых необходимо переносить ANSI.

Пример 1

Следующая программа открывает два файла. Она использует 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 );
}
The file 'crt_fopen.c' was opened
The file 'data2' was opened
Number of files closed by _fcloseall: 1

Пример 2

Следующая программа создает файл (или перезаписывает его, если имеется) в текстовом режиме с кодировкой Юникода. Затем она записывает две строки в файл и закрывает его. Выходные данные — это файл с именем _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;
}

См. также

Потоковый ввод-вывод
Интерпретация последовательностей многобайтовых символов
fclose, _fcloseall
_fdopen, _wfdopen
ferror
_fileno
freopen, _wfreopen
_open, _wopen
_setmode
_sopen, _wsopen