fopen_s, _wfopen_s
Otwiera plik.Te wersje fopen, _wfopen mają wzmocnione zabezpieczenia, co opisano w Funkcje zabezpieczeń w CRT
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
[poza] pFile
Wskaźnik do wskaźnika pliku, który odbierze wskaźnik do otwartego pliku.[w] filename
Nazwa pliku.[in] mode
Dozwolony typ dostępu.
Wartość zwracana
Zero, jeśli operacja się powiedzie; w przeciwnym razie, kod błędu.Aby uzyskać więcej informacji na temat tych kodów błędu, zobacz errno, _doserrno, _sys_errlist, and _sys_nerr.
Warunki błędów
pFile |
filename |
mode |
Wartość zwrócona |
Zawartość pFile |
---|---|---|---|---|
NULL |
jakakolwiek |
jakakolwiek |
EINVAL |
niezmienione |
jakakolwiek |
NULL |
jakakolwiek |
EINVAL |
niezmienione |
jakakolwiek |
jakakolwiek |
NULL |
EINVAL |
niezmienione |
Uwagi
Pliki otwarte przez fopen_s i _wfopen_s nie mogą być udostępniane.Jeśli jest wymagane aby plik mógł być udostępniany, należy użyć _fsopen, _wfsopen z odpowiednią stałą trybu udostępniania, na przykład _SH_DENYNO dla udostępniania odczytu/zapisu.
Funkcja fopen_s otwiera plik, który jest określony przez filename._wfopen_s to wersja znaku dwubajtowego fopen_s; argumenty do _wfopen_s to ciągi znaku dwubajtowego._wfopen_s i fopen_s zachowują się identycznie w innych przypadkach.
Funkcja fopen_s akceptuje ścieżki, które są ważne w systemie plików w momencie wykonywania. Ścieżki UNC i ścieżki, które zawierają mapowane dyski sieciowe są akceptowane przez funkcję fopen_s tak długo, jak system, na którym wykonywany jest kod, ma dostęp do współdzielonego lub mapowanego dysku sieciowego, w czasie wykonywania.Podczas konstruowania ścieżki dla fopen_s nie należy zakładać, że dyski, ścieżki lub udziały sieciowe będą dostępne w środowisku wykonawczym.Jako separator katalogu w ścieżce można użyć ukośnika (/) lub ukośnika odwrotnego (\).
Te funkcje sprawdzają poprawność swoich parametrów.Jeśli pFile, filename lub mode jest pustym wskaźnikiem, funkcje te generują wyjątek nieprawidłowego parametru, jak opisano w Sprawdzanie poprawności parametru.
Należy zawsze sprawdzać zwracaną wartość, aby sprawdzić, czy funkcja zakończyła się pomyślnie, przed wykonaniem wszelkich dalszych operacji na pliku.Jeśli wystąpi błąd, zwracany jest kod błędu i ustawiona jest zmienna globalna errno.Aby uzyskać więcej informacji, zobacz errno, _doserrno, _sys_errlist, and _sys_nerr.
Obsługa formatu Unicode
Funkcja fopen_s obsługuje strumienie pliku w formacie Unicode.Aby otworzyć nowy lub istniejący plik w formacie Unicode, należy przekazać flagę ccs, która określa wymagane kodowanie dla fopen_s:
fopen_s(&fp, "newfile.txt", "rw, ccs=encoding");
Dozwolone wartości encoding to UNICODE, UTF-8 i UTF-16LE.Jeśli ma określonej wartości dla encoding funkcja fopen_s używa kodowania ANSI.
Jeśli plik już istnieje i jest otwarty w celu odczytu lub dołączania to znak kolejności bajtów (BOM) określa kodowanie, jeśli jest on obecny w pliku.Kodowanie określone przez znak BOM ma pierwszeństwo nad kodowaniem, które jest określone przez flagę ccs.Kodowanie ccs jest używane tylko wtedy, gdy znak BOM nie jest określony lub gdy plik jest nowym plikiem.
[!UWAGA]
Wykrywanie znaku BOM ma zastosowanie tylko do plików, które są otwarte w trybie Unicode. Jest tak przez przekazanie flagi ccs.
W następującej tabeli podsumowano tryby dla różnych flag ccs, które są przekazane do funkcji fopen_s i dla znaków kolejności bajtów w pliku.
Standardy kodowania używane na podstawie flagi ccs i znaku BOM
flaga ccs |
Brak znaku BOM (lub nowy plik) |
Znak BOM: UTF-8 |
Znak 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 |
Pliki, które są otwarte do pisania w trybie Unicode mają automatycznie zapisywany znak BOM.
Jeśli mode ma wartość "a, ccs=<encoding>", funkcja fopen_s najpierw próbuje otworzyć plik z dostępem do odczytu i zapisu.W przypadku powodzenia, funkcja odczytuje znak BOM, aby określić kodowanie pliku. W przypadku niepowodzenia, funkcja używa domyślnego kodowania pliku.Następnie w obu przypadkach funkcja fopen_s ponowne otwiera plik z dostępem tylko do zapisu. (Dotyczy to tylko trybu a a nie dotyczy trybu a+.)
Rutynowe mapowania zwykłego tekstu
Procedura Tchar.h |
_UNICODE & _MBCS nie zdefiniowano |
_MBCS zdefiniowano |
_UNICODE zdefiniowany |
---|---|---|---|
_tfopen_s |
fopen_s |
fopen_s |
_wfopen_s |
Ciąg znaków mode określa rodzaj dostępu, który jest wymagany dla pliku, w następujący sposób.
"r"
Otwarty do odczytu.Jeśli plik nie istnieje lub nie można go znaleźć, wywołanie funkcji fopen_s kończy się niepowodzeniem."w"
Otwiera pusty plik do zapisu.Jeśli plik istnieje, jego zawartość zostaje zniszczona."a"
Otwiera plik z możliwością zapisu na końcu pliku (dołączanie) bez usuwania znacznika EOF, przed zapisaniem nowych danych do pliku.Tworzy plik, jeśli nie istnieje."r+"
Otwiera zarówno do odczytu jak i do zapisu. (Plik musi istnieć)."w+"
Otwiera pusty plik zarówno do odczytu jak i do zapisu.Jeśli plik istnieje, jego zawartość zostaje zniszczona."a+"
Otwiera do odczytu i dołączania.Operacja dołączania obejmuje usunięcie znacznika EOF, zanim nowe dane zostanę zapisane do pliku a znacznik EOF jest przywracany po zakończeniu operacji zapisu.Tworzy plik, jeśli nie istnieje.
Gdy plik jest otwarty za pomocą typu dostępu "a" lub "a+" wszystkie operacje zapisu występują na końcu pliku.Wskaźnik pliku może być przeniesiony za pomocą fseek lub rewind ale jest on zawsze przenoszony z powrotem na koniec pliku, zanim zostanie przeprowadzona jakakolwiek operacja zapisu, tak aby nie zastąpić istniejących danych.
Tryb "a" nie usuwa znacznika EOF przed wykonaniem operacji dołączenia na pliku.Po wystąpieniu operacji dołączania, polecenie MS-DOS TYPE pokazuje tylko dane znajdujące się przed oryginalnym znacznikiem EOF i nie pokazuje żadnych danych, które zostały dołączone do pliku.Tryb "a+" usuwa znacznik EOF przed wykonaniem operacji dołączania na pliku.Po operacji dołączania, polecenie MS-DOS TYPE pokazuje wszystkie dane w pliku.Tryb "a+" jest wymagany do wykonania operacji dołączania do pliku strumienia, który jest przerywany przy użyciu skrótu CRTL + Z, określającego znacznik EOF.
Gdy określony jest typ dostępu "r+","w+", lub "a+" dozwolone są zarówno operacje odczytu jak i zapisu. (Ten plik powinien być otwarty do "aktualizacji".) Jednak, po przełączeniu się z odczytu do zapisu, operacja wprowadzania musi napotkać znacznik EOF.Jeśli znacznik EOF nie istnieje, należy użyć interwencyjnego wywołania funkcji położenia pliku.Funkcje położenia pliku to fsetpos, fseek i rewind.Po przełączeniu się z zapisu do odczytu, należy użyć interwencyjnego wywołania funkcji fflush lub funkcji położenia pliku.
Oprócz powyższych wartości, następujące znaki mogą być zawarte w mode, aby określić tryb translacji znaków nowego wiersza:
- t
Otwórz w trybie tekstowym (tłumaczonym).W tym trybie skrót CTRL + Z jest interpretowany jako znak końca pliku na wejściu.W przypadku plików otwartych do odczytu/zapisu w trybie "a+", funkcja fopen_s sprawdza czy na końcu pliku istnieje CTRL + Z i usuwa go, jeśli to możliwe.Jest to wykonywane, ponieważ poruszanie się wewnątrz pliku za pomocą fseek i ftell, który kończy się z CRTL + Z może powodować, że fseek będzie działać nieprawidłowo w pobliżu końca pliku.
Dodatkowo, w trybie tekstowym, na wejściu kombinacje powrotu karetki i znaku wysuwu wiersza są tłumaczone na pojedyncze znaki wysuwu wiersza, a na wyjściu znaki wysuwu wiersza są tłumaczone na kombinacje powrotu karetki i znaku wysuwu wiersza.Kiedy funkcja strumienia we/wy kodowania Unicode działa w trybie tekstowym (ustawienie domyślne), zakłada się, że strumień źródłowy lub docelowy jest sekwencją znaków wielobajtowych.W związku z tym, funkcje strumienia wejściowego kodowania Unicode, konwertują znaki wielobajtowe do ciągów wieloznakowych (tak jak za pomocą wywołania funkcji mbtowc).Z tego samego powodu, funkcje strumienia wyjściowego kodowania Unicode konwertują ciągi wieloznakowe na znaki wielobajtowe (tak jak za pomocą wywołania funkcji wctomb).
- b
Otwórz w trybie binarnym (nieprzetłumaczony). Tłumaczenia zawierające znaki powrotu karetki i wysuwu wiersza są odrzucane.
Jeśli wartość t lub b nie jest podana w parametrze mode, domyślny tryb translacji jest zdefiniowany przez zmienną globalną _fmode.Jeśli wartość t lub b poprzedza argument, funkcja kończy się niepowodzeniem i zwraca NULL.
Aby uzyskać więcej informacji dotyczących korzystania z trybu tekstowego i binarnego w kodowaniu Unicode oraz na temat wielobajtowych strumieni we/wy, zobacz Tryb tekstowy i binarny dla plików we/wy i Strumień we/wy kodowania Unicode w trybie tekstowym i binarnym.
c
Włącz flagę przekazywania dla skojarzonego parametru filename tak, aby zawartość buforu pliku została zapisana bezpośrednio na dysku, jeśli zostanie wywołana funkcja fflush lub _flushall.n
Resetuj flagę przekazywania dla skojarzonego parametru filename na wartość "no-commit". Domyślnie włączone.Zastępuje również globalną flagę przekazywania jeśli program jest połączony z COMMODE.OBJ.Wartość domyślna globalnej flagi przekazywania to "no-commit", chyba że program jest jawnie połączony z COMMODE.OBJ (zobacz Opcje łącz).N
Określa, że plik nie jest dziedziczony przez procesy podrzędne.S
Określa, że buforowanie jest zoptymalizowane pod kątem dostępu sekwencyjnego do dysku, ale nie ogranicza się do niego.R
Określa, że buforowanie jest zoptymalizowane pod kątem dostępu losowego do dysku, ale nie ogranicza się do niego.T
Określa plik jako tymczasowy.Jeśli to możliwe, nie jest on opróżniany na dysku.D
Określa plik jako tymczasowy.Jest on usuwany po zamknięciu ostatniego wskaźnika do pliku.ccs=ENCODING
Określ zakodowany zestaw znaków, który ma być użyty (UTF-8, UTF-16LE i UNICODE) dla tego pliku.Pozostaw to nieokreślone, jeśli chcesz używać kodowania ANSI.
Prawidłowe znaki ciągu tekstowego mode używane w funkcji fopen_s i _fdopen odpowiadają argumentom oflag używanych w funkcjach _open i _sopen, w następujący sposób.
Znaki w ciągu znaków określającym tryb |
Równoważna wartość oflag dla _open/_sopen |
---|---|
a |
_O_WRONLY | _O_APPEND (zazwyczaj _O_WRONLY | _O_CREAT |_O_APPEND) |
a+ |
_O_RDWR | _O_APPEND (zazwyczaj _O_RDWR | _O_APPEND | _O_CREAT ) |
r |
_O_RDONLY |
r+ |
_O_RDWR |
w |
_O_WRONLY (zazwyczaj _O_WRONLY |_O_CREAT | _O_TRUNC) |
w+ |
_O_RDWR (zazwyczaj _O_RDWR | _O_CREAT | _O_TRUNC ) |
b |
_O_BINARY |
t |
_O_TEXT |
c |
Brak |
n |
Brak |
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 |
Podczas używania trybu rb nie ma potrzeby przenoszenia kodu i należy oczekiwać odczytywania wielu plików oraz/lub nie trzeba martwić się wydajnością sieci. Pliki Win32 z mapowaną pamięcią mogą również być jedną z opcji.
Wymagania
Funkcja |
Wymagany nagłówek |
---|---|
fopen_s |
<stdio.h> |
_wfopen_s |
<stdio.h> lub <wchar.h> |
Dodatkowe informacje o zgodności – zobacz: Zgodność we Wprowadzeniu.
Biblioteki
Wszystkie wersje Bibliotek uruchomieniowych C.
Opcje c, n i t dla parametru mode są rozszerzeniami firmy Microsoft dla funkcji fopen_s i _fdopen i nie powinny być używane tam, gdzie pożądana jest przenośność kodowania ANSI.
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" does not 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+" );
if( err == 0 )
{
printf( "The file 'data2' was opened\n" );
}
else
{
printf( "The file 'data2' was not opened\n" );
}
// Close stream if it is not 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 );
}