Udostępnij za pośrednictwem


fopen_s, _wfopen_s

Otwiera plik. Te wersje programu fopen _wfopenmają ulepszenia zabezpieczeń zgodnie z opisem w temacie Funkcje zabezpieczeń w narzędziu CRT.

Składnia

errno_t fopen_s(
   FILE** pFile,
   const char *filename,
   const char *mode
);
errno_t _wfopen_s(
   FILE** pFile,
   const wchar_t *filename,
   const wchar_t *mode
);

Parametry

pFile
Wskaźnik do wskaźnika pliku, który odbiera wskaźnik do otwartego pliku.

filename
Nazwa pliku do otwarcia.

mode
Typ dozwolonego dostępu.

Wartość zwracana

Zero w przypadku powodzenia; kod błędu dotyczący błędu. Aby uzyskać więcej informacji na temat tych kodów błędów, zobacz errno, _doserrno, _sys_errlisti _sys_nerr.

Warunki błędu

pFile filename mode Wartość zwracana Zawartość pFile
NULL dowolny dowolny EINVAL Niezmienione
dowolny NULL dowolny EINVAL Niezmienione
dowolny dowolny NULL EINVAL Niezmienione

Uwagi

Funkcje fopen_s i _wfopen_s nie mogą otworzyć pliku do udostępniania. Jeśli musisz udostępnić plik, użyj _fsopen lub _wfsopen z odpowiednią stałą trybem udostępniania — na przykład użyj funkcji _SH_DENYNO udostępniania do odczytu/zapisu.

Funkcja fopen_s otwiera plik określony przez filename. _wfopen_s jest wersją fopen_s szerokoznakową, a argumenty do _wfopen_s są ciągami o szerokim znaku. _wfopen_s i fopen_s zachowywać się identycznie, w przeciwnym razie.

fopen_s akceptuje ścieżki, które są prawidłowe w systemie plików w momencie wykonywania; Ścieżki i ścieżki UNC, które obejmują zamapowane dyski sieciowe, są akceptowane fopen_s tak długo, jak system wykonujący kod ma dostęp do udziału lub zamapowanego dysku sieciowego w czasie wykonywania. Podczas tworzenia ścieżek dla fopen_sprogramu nie należy zakładać dostępności dysków, ścieżek ani udziałów sieciowych w środowisku wykonywania. Jako separatory katalogów w ścieżce można użyć ukośników (/) lub ukośników odwrotnych (\).

Te funkcje weryfikują swoje parametry. Jeśli pFileelement , filenamelub mode jest wskaźnikiem o wartości null, te funkcje generują nieprawidłowy wyjątek parametru, zgodnie z opisem w temacie Walidacja parametru.

Zawsze sprawdzaj wartość zwracaną, aby sprawdzić, czy funkcja zakończyła się pomyślnie przed wykonaniem dalszych operacji w pliku. Jeśli wystąpi błąd, zostanie zwrócony kod błędu, a zmienna globalna errno zostanie ustawiona. Aby uzyskać więcej informacji, zobacz errno, _doserrno, _sys_errlisti _sys_nerr.

Domyślnie stan globalny tej funkcji jest zakresem aplikacji. Aby go zmienić, zobacz Stan globalny w CRT.

Obsługa formatu Unicode

fopen_s obsługuje strumienie plików Unicode. Aby otworzyć nowy lub istniejący plik Unicode, przekaż flagę określającą ccs żądane kodowanie na fopen_s, na przykład:

fopen_s(&fp, "newfile.txt", "w+, ccs=UNICODE");

Dozwolone wartości flagi ccs to UNICODE, UTF-8i UTF-16LE. Jeśli dla parametru nie określono ccsżadnej wartości , fopen_s używa kodowania ANSI.

Jeśli plik już istnieje i jest otwarty do odczytu lub dołączania, znacznik kolejności bajtów (BOM), jeśli istnieje w pliku, określa kodowanie. Kodowanie BOM ma pierwszeństwo przed kodowaniem określonym przez flagę ccs . ccs Kodowanie jest używane tylko wtedy, gdy nie ma modelu BOM lub jeśli plik jest nowym plikiem.

Uwaga

Wykrywanie BOM dotyczy tylko plików otwartych w trybie Unicode; oznacza to, przekazując flagę ccs .

W poniższej tabeli przedstawiono podsumowanie trybów dla różnych ccs wartości flag, które są podane dla fopen_s elementów BOM i w pliku .

Kodowanie używane na ccs podstawie flagi i modelu BOM

ccs flaga Brak modelu BOM (lub nowego pliku) BOM: UTF-8 BOM: UTF-16
UNICODE UTF-8 UTF-8 UTF-16LE
UTF-8 UTF-8 UTF-8 UTF-16LE
UTF-16LE UTF-16LE UTF-8 UTF-16LE

Pliki otwierane do zapisywania w trybie Unicode mają automatycznie zapisywany BOM.

Jeśli mode element to "a, ccs=UNICODE", "a, ccs=UTF-8"lub "a, ccs=UTF-16LE", fopen_s najpierw próbuje otworzyć plik z dostępem do odczytu i zapisu. Jeśli operacja zakończy się pomyślnie, funkcja odczytuje element BOM, aby określić kodowanie pliku; jeśli nie powiedzie się, funkcja używa domyślnego kodowania dla pliku. W obu przypadkach fopen_s ponownie otwiera plik z dostępem tylko do zapisu. (To zachowanie dotyczy a tylko trybu, a nie a+.)

Ciąg mode znaków określa rodzaj dostępu żądanego dla pliku w następujący sposób.

mode Access
"r" Otwiera plik do czytania. Jeśli plik nie istnieje lub nie można go odnaleźć, fopen_s wywołanie nie powiedzie się.
"w" Otwiera pusty plik do zapisu. Jeśli dany plik istnieje, jego zawartość zostanie zniszczona.
"a" Otwiera plik do zapisu na końcu pliku (dołączanie) bez usuwania znacznika końca pliku (EOF), zanim nowe dane są zapisywane w pliku. Tworzy plik, jeśli nie istnieje.
"r+" Otwiera plik zarówno do czytania, jak i zapisu. Plik musi istnieć.
"w+" Otwiera pusty plik do odczytu i zapisu. Jeśli plik istnieje, jego zawartość zostanie zniszczona.
"a+" Otwiera plik do odczytu i dołączania. Operacja dołączania obejmuje usunięcie znacznika EOF przed zapisaniem nowych danych w pliku. Znacznik EOF nie jest przywracany po zakończeniu pisania. Tworzy plik, jeśli nie istnieje.

Po otwarciu "a" pliku przy użyciu typu dostępu lub "a+" wszystkie operacje zapisu są wykonywane na końcu pliku. Wskaźnik pliku można zmienić przy użyciu polecenia fseek lub rewind, ale zawsze jest przenoszony z powrotem na koniec pliku, zanim zostanie przeprowadzona żadna operacja zapisu, aby nie można było zastąpić istniejących danych.

Tryb "a" nie usuwa znacznika EOF przed dołączeniem do pliku. Po dołączeniu polecenie MS-DOS TYPE wyświetla tylko dane do oryginalnego znacznika EOF, a nie wszystkie dane dołączone do pliku. Tryb "a+" usuwa znacznik EOF przed dołączeniem do pliku. Po dołączeniu polecenie MS-DOS TYPE wyświetla wszystkie dane w pliku. Tryb "a+" jest wymagany do dołączania do pliku strumienia zakończonego znacznikiemCTRL+ Z EOF.

Po określeniu "r+"typu , "w+"lub "a+" dostępu zarówno odczyt, jak i zapis są dozwolone. (Mówi się, że plik jest otwarty dla "update". Jednak po przełączeniu się z odczytu na zapis operacja wejściowa musi napotkać znacznik EOF. Jeśli nie ma znacznika EOF, musisz użyć interweniowania wywołania funkcji pozycjonowania plików. Funkcje pozycjonowania plików to fsetpos, fseeki rewind. W przypadku przełączania się z zapisu na odczyt należy użyć interweniowania wywołania funkcji fflush lub do funkcji pozycjonowania plików.

Począwszy od C11, można dołączyć "x" do "w" funkcji lub "w+" spowodować niepowodzenie funkcji, jeśli plik istnieje, zamiast zastępować go.

Oprócz poprzednich wartości można uwzględnić następujące znaki, mode aby określić tryb tłumaczenia dla znaków nowego wiersza:

mode Modyfikator Tryb tłumaczenia
t Otwórz w trybie tekstowym (przetłumaczonym). Kombinacje zestawienia powrotu karetki (CR-LF) są tłumaczone na pojedyncze kanały informacyjne (LF) w danych wejściowych, a znaki LF są tłumaczone na kombinacje CR-LF w danych wyjściowych. Ctrl+Z jest interpretowany jako znak końca pliku w danych wejściowych.
b Otwórz w trybie binarnym (nieprzetłumaczonym); tłumaczenia obejmujące znaki powrotu karetki i znaków kanału informacyjnego wiersza są pomijane.

W trybie CTRL+tekstowym (przetłumaczonym) znak Z jest interpretowany jako znak końca pliku w danych wejściowych. W przypadku plików otwartych do odczytu/zapisu "a+"za pomocą polecenia fopen_s program sprawdza CTRL+wartość Z na końcu pliku i usuwa go, jeśli to możliwe. Jest on usuwany, ponieważ użycie elementu fseek i ftell do przeniesienia w pliku kończącym się ciągiemCTRL+ Z może spowodować fseek nieprawidłowe zachowanie na końcu pliku.

Ponadto w trybie tekstowym kombinacje powrotu karetki/wiersza (CRLF) są tłumaczone na znaki jednowierszowego kanału informacyjnego (LF) w danych wejściowych, a znaki LF są tłumaczone na kombinacje CRLF w danych wyjściowych. Gdy funkcja Strumienia-We/Wy Unicode działa w trybie tekstowym (wartość domyślna), przyjmuje się, że strumień źródłowy lub docelowy jest sekwencją znaków wielobajtowych. Funkcje wprowadzania strumienia Unicode konwertują znaki wielobajtowe na znaki szerokie (tak jak wywołanie mbtowc funkcji). Z tego samego powodu funkcje przesyłania strumieniowego Unicode konwertują znaki szerokie na znaki wielobajtowe (tak jak w przypadku wywołania wctomb funkcji).

Jeśli t wartość lub b nie jest podana w programie mode, domyślny tryb tłumaczenia jest definiowany przez zmienną globalną _fmode. Jeśli t argument lub b jest poprzedzony prefiksem, funkcja kończy się niepowodzeniem i zwraca wartość NULL.

Aby uzyskać więcej informacji na temat używania trybów tekstowych i binarnych w standardach Unicode i wielobajtowych strumienia we/wy, zobacz We/Wy i We/Wy w formacie tekstowym i binarnym w plikach tekstowych i binarnych w trybie tekstowym i binarnym.

mode Modyfikator Zachowanie
c Włącz flagę zatwierdzania skojarzonej filename , aby zawartość buforu plików została zapisana bezpośrednio na dysku, jeśli fflush jest wywoływana wartość lub _flushall .
n Zresetuj flagę zatwierdzenia dla skojarzonego filename z "no-commit". Ta flaga jest domyślna. Zastępuje również flagę zatwierdzenia globalnego, jeśli połączysz program za pomocą polecenia COMMODE.OBJ. Domyślna flaga zatwierdzenia globalnego to "no-commit", chyba że jawnie połączysz program z COMMODE.OBJ (zobacz Opcje łącza).
N Określa, że plik nie jest dziedziczony przez procesy podrzędne.
S Określa, że buforowanie jest zoptymalizowane pod kątem, ale nie ogranicza się do sekwencyjnego dostępu z dysku.
R Określa, że buforowanie jest zoptymalizowane pod kątem, ale nie ogranicza się do losowego dostępu z dysku.
T Określa plik, który nie jest zapisywany na dysku, chyba że wymaga go wykorzystanie pamięci.
D Określa plik tymczasowy, który jest usuwany po zamknięciu ostatniego wskaźnika pliku.
ccs=UNICODE Określa UNICODE jako zakodowany zestaw znaków do użycia dla tego pliku. Pozostaw nieokreślony, jeśli chcesz kodować ANSI.
ccs=UTF-8 Określa UTF-8 jako zakodowany zestaw znaków do użycia dla tego pliku. Pozostaw nieokreślony, jeśli chcesz kodować ANSI.
ccs=UTF-16LE Określa UTF-16LE jako zakodowany znak ustawiony do użycia dla tego pliku. Pozostaw nieokreślony, jeśli chcesz kodować ANSI.

Prawidłowe znaki dla ciągu używanego mode w fopen_s systemie i _fdopen odpowiadają oflag argumentom używanym w _open systemach i _sopen, w następujący sposób.

Znaki w mode ciągu Równoważna oflag wartość dla _open/_sopen
a _O_WRONLY | _O_APPEND (zwykle _O_WRONLY | _O_CREAT | _O_APPEND)
a+ _O_RDWR | _O_APPEND (zwykle _O_RDWR | _O_APPEND | _O_CREAT)
R _O_RDONLY
r+ _O_RDWR
w _O_WRONLY (zwykle _O_WRONLY | _O_CREAT | _O_TRUNC)
w+ _O_RDWR (zwykle **_O_RDWR | _O_CREAT | _O_TRUNC)
b _O_BINARY
t _O_TEXT (przetłumaczone)
c Brak
n Brak
D _O_TEMPORARY
R _O_RANDOM
S _O_SEQUENTIAL
T _O_SHORTLIVED
ccs=UNICODE _O_WTEXT
ccs=UTF-8 _O_UTF8
ccs=UTF-16LE _O_UTF16

Opcje c, , RtnSTi mode D są rozszerzeniami fopen_s _wfopen_s firmy Microsoft i nie powinny być używane, gdy chcesz przenośność ANSI.

Jeśli używasz rb trybu, pliki Win32 mapowane na pamięć mogą być również opcją, jeśli nie musisz przenosić kodu, oczekujesz, że odczyt dużej części pliku lub nie zależy Ci na wydajności sieci.

Dotyczy T i D:

  • T program unika zapisywania pliku na dysku, o ile nie wymaga tego wykorzystanie pamięci. Aby uzyskać więcej informacji, zobacz FILE_ATTRIBUTE_TEMPORARY w temacie Stałe atrybutów pliku, a także ten wpis w blogu Jest to tylko tymczasowe.
  • D określa zwykły plik zapisywany na dysku. Różnica polega na tym, że jest on automatycznie usuwany po zamknięciu. Można połączyć TD w celu uzyskania obu semantyki.

Wymagania

Function Wymagany nagłówek Nagłówek języka C++
fopen_s <stdio.h> <cstdio>
_wfopen_s <stdio.h> lub <wchar.h> <cstdio>

Aby uzyskać więcej informacji na temat zgodności standardów i konwencji nazewnictwa w bibliotece środowiska uruchomieniowego języka C, zobacz Zgodność.

Mapowania procedur tekstu ogólnego

<tchar.h> rutyna _UNICODE i _MBCS niezdefiniowane _MBCS zdefiniowany _UNICODE zdefiniowany
_tfopen_s fopen_s fopen_s _wfopen_s

Biblioteki

Wszystkie wersje bibliotek czasu wykonywania języka C.

Przykład

// crt_fopen_s.c
// 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 )
{
   errno_t err;

   // Open for read (will fail if file "crt_fopen_s.c" doesn't exist)
   err  = fopen_s( &stream, "crt_fopen_s.c", "r" );
   if( err == 0 )
   {
      printf( "The file 'crt_fopen_s.c' was opened\n" );
   }
   else
   {
      printf( "The file 'crt_fopen_s.c' was not opened\n" );
   }

   // Open for write
   err = fopen_s( &stream2, "data2", "w+, ccs=UTF-8" );
   if( err == 0 )
   {
      printf( "The file 'data2' was opened\n" );
   }
   else
   {
      printf( "The file 'data2' was not opened\n" );
   }

   // Close stream if it isn't NULL
   if( stream )
   {
      err = fclose( stream );
      if ( err == 0 )
      {
         printf( "The file 'crt_fopen_s.c' was closed\n" );
      }
      else
      {
         printf( "The file 'crt_fopen_s.c' was not closed\n" );
      }
   }

   // All other files are closed:
   int numclosed = _fcloseall( );
   printf( "Number of files closed by _fcloseall: %u\n", numclosed );
}
The file 'crt_fopen_s.c' was opened
The file 'data2' was opened
Number of files closed by _fcloseall: 1

Zobacz też

We/Wy strumienia
fclose, _fcloseall
_fdopen, _wfdopen
ferror
_fileno
freopen, _wfreopen
_open, _wopen
_setmode