fopen_s
, _wfopen_s
Otwiera plik. Te wersje programu fopen
_wfopen
mają 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_errlist
i _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_s
programu 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 pFile
element , filename
lub 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_errlist
i _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-8
i 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
, fseek
i 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
, , R
t
n
S
T
i 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, zobaczFILE_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