Udostępnij za pośrednictwem


fopen, _wfopen

Otwiera plik. Dostępne są bardziej bezpieczne wersje tych funkcji, które wykonują większą weryfikację parametrów i zwracają kody błędów; zobacz fopen_s, _wfopen_s.

Składnia

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

Parametry

filename
Nazwa pliku.

mode
Rodzaj dostępu, który jest włączony.

Wartość zwracana

Każda z tych funkcji zwraca wskaźnik do otwartego pliku. Wartość wskaźnika o wartości null wskazuje błąd. Jeśli filename lub mode jest NULL ciągiem pustym, te funkcje wyzwalają nieprawidłową procedurę obsługi parametrów opisaną w temacie Weryfikacja parametrów. Jeśli wykonanie jest dozwolone do kontynuowania, te funkcje zwracają NULL i ustawiają wartość errno EINVAL.

Aby uzyskać więcej informacji, zobacz errno, _doserrno, _sys_errlisti _sys_nerr.

Uwagi

Funkcja fopen otwiera plik określony przez filename. Domyślnie wąski filename ciąg jest interpretowany przy użyciu strony kodowej ANSI (CP_ACP). W aplikacjach klasycznych systemu Windows można ją zmienić na stronę kodową OEM (CP_OEMCP) przy użyciu SetFileApisToOEM funkcji . Możesz użyć AreFileApisANSI funkcji, aby określić, czy filename jest interpretowana przy użyciu anSI, czy domyślnej strony kodowej producenta OEM systemu. _wfopenjest wersją szerokoznakową ; fopen_wfopen argumenty są ciągami o szerokim znaku. _wfopen W przeciwnym razie i fopen zachowują się identycznie. _wfopen Użycie tylko nie wpływa na kodowany zestaw znaków używany w strumieniu plików.

fopen akceptuje ścieżki, które są prawidłowe w systemie plików w momencie wykonywania; fopen Akceptuje ścieżki i ścieżki UNC, które obejmują zamapowane dyski sieciowe, o ile system wykonujący kod ma dostęp do udziału lub zamapowanego dysku w czasie wykonywania. Podczas tworzenia ścieżek dla fopenprogramu upewnij się, że dyski, ścieżki lub udziały sieciowe są dostępne w środowisku wykonywania. Można użyć ukośników () lub ukośników odwrotnych (/\) jako separatorów katalogu w ścieżce.

Zawsze sprawdzaj wartość zwracaną, aby sprawdzić, czy wskaźnik ma wartość NULL przed wykonaniem innych operacji w pliku. Jeśli wystąpi błąd, zmienna errno globalna jest ustawiona i może służyć do uzyskiwania określonych informacji o błędzie. 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 obsługuje strumienie plików Unicode. Aby otworzyć plik Unicode, przekaż flagę określającą ccs=encoding żądane kodowanie do fopen, w następujący sposób.

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

Dozwolone wartości kodowania ccs to UNICODE, UTF-8i UTF-16LE.

Po otwarciu pliku w trybie Unicode funkcje wejściowe tłumaczą dane odczytywane z pliku na dane UTF-16 przechowywane jako typ wchar_t. Funkcje zapisu w pliku otwartym w trybie Unicode oczekują zawierających dane UTF-16 przechowywane jako typ wchar_t. Jeśli plik jest zakodowany jako UTF-8, dane UTF-16 są tłumaczone na utF-8 podczas zapisywania. Zawartość zakodowana w formacie UTF-8 jest tłumaczona na kodOWANIE UTF-16 podczas jego odczytywania. Próba odczytania lub zapisania nieparzystej liczby bajtów w trybie Unicode powoduje błąd weryfikacji parametru. Aby odczytywać lub zapisywać dane przechowywane w programie jako UTF-8, użyj trybu pliku tekstowego lub binarnego zamiast trybu Unicode. Odpowiadasz za każde wymagane tłumaczenie kodowania.

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

Uwaga

Wykrywanie BOM dotyczy tylko plików otwartych w trybie Unicode (czyli przez przekazanie flagi ccs ).

W poniższej tabeli przedstawiono podsumowanie trybów używanych dla różnych ccs flag podanych w fopen pliku i znaczników kolejności bajtów.

Kodowanie używane na podstawie flagi ccs i BOM

ccs flaga Brak modelu BOM (lub nowego pliku) 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

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

Jeśli mode ma a, ccs=encoding wartość encoding , fopen najpierw spróbuj otworzyć plik przy użyciu dostępu zarówno do odczytu, jak i zapisu. Jeśli ta akcja powiedzie się, funkcja odczytuje element BOM, aby określić kodowanie pliku. Jeśli zakończy się to niepowodzeniem, funkcja używa domyślnego kodowania dla pliku. W obu przypadkach fopen ponownie otwiera plik przy użyciu dostępu tylko do zapisu. (To zachowanie dotyczy "a" tylko trybu, a nie "a+" trybu).

Mapowania procedur tekstu ogólnego

TCHAR.H rutyna _UNICODE i _MBCS niezdefiniowane _MBCS zdefiniowany _UNICODE zdefiniowany
_tfopen fopen fopen _wfopen

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 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+" typu dostępu wszystkie operacje zapisu są wykonywane na końcu pliku. Wskaźnik pliku można zmienić za pomocą polecenia fseek lub rewind, ale zawsze jest przenoszony z powrotem na koniec pliku przed wykonaniem dowolnej operacji zapisu. W związku z tym istniejące dane nie mogą być zastępowane.

Tryb "a" nie usuwa znacznika EOF przed dołączeniem go do pliku. Po dołączeniu polecenie MS-DOS TYPE wyświetla tylko dane do oryginalnego znacznika EOF, a nie żadne dane dołączone do pliku. Przed dołączeniem go do pliku "a+" tryb powoduje usunięcie znacznika EOF. 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ą włączone (plik ma być otwarty dla "aktualizacji"). Jednak po przełączeniu się z odczytu na zapis operacja wejściowa musi napotkać znacznik EOF. Jeśli nie ma EOF, musisz użyć interweniowania wywołania funkcji pozycjonowania pliku. Funkcje pozycjonowania plików to fsetpos, fseeki rewind. Po przełączeniu się z zapisu do odczytu należy użyć interweniowania wywołania funkcji fflush pozycjonowania pliku lub do funkcji pozycjonowania pliku.

Oprócz wcześniejszych wartości można dołączyć następujące znaki, aby mode 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. Ponadto CTRL+Z są interpretowane 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 tekstowym Z CTRL+ jest interpretowany jako znak EOF w danych wejściowych. W plikach, które są otwierane do odczytu/zapisu przy użyciu polecenia "a+", fopen sprawdzaCTRL+ wartość Z na końcu pliku i usuwa go, jeśli jest 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.

W trybie tekstowym kombinacje zestawienia powrotu karetki (CRLF) są tłumaczone na znaki jednowierszowego kanału informacyjnego (LF) w danych wejściowych, a znaki LF są tłumaczone na kombinacje CRLF na 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. W związku z tym funkcje przesyłania strumieniowego 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 we/wy strumienia, zobacz We/Wy i We/Wy plików w trybie tekstowym i binarnym w trybie tekstowym i binarnym w trybie tekstowym i binarnym.

Aby określić więcej zachowań, można dołączyć mode następujące opcje.

mode Modyfikator Zachowanie
x Wymusza niepowodzenie funkcji, jeśli filename już istnieje. Można używać tylko z specyfikatorami "w" lub "w+".
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 z COMMODE.OBJ. Domyślna flaga zatwierdzenia globalnego to "no-commit", chyba że jawnie połączysz program z modułem 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=encoding Określa zakodowany zestaw znaków do użycia (jeden z UTF-8, UTF-16LElub UNICODE) dla tego pliku. Pozostaw nieokreślony, jeśli chcesz kodować ANSI. Ta flaga jest oddzielona od flag poprzedzających ją przecinkiem (,). Na przykład: FILE *f = fopen("newfile.txt", "rt+, ccs=UTF-8");.

Prawidłowe znaki dla ciągu używanego mode w fopen 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)
x _O_EXCL
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

Jeśli używasz rb trybu, nie musisz przenosić kodu i jeśli oczekujesz, że odczyt większości dużego pliku lub nie obawiasz się wydajności sieci, możesz również rozważyć, czy używać pamięci mapowanych plików Win32 jako opcji.

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.

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

Wymagania

Function Wymagany nagłówek
fopen <stdio.h>
_wfopen <stdio.h> lub <wchar.h>

_wfopen to rozszerzenie firmy Microsoft. Aby uzyskać więcej informacji na temat zgodności, zobacz Zgodność.

Opcje c, , tRnSTi mode D są rozszerzeniami firmy Microsoft i fopen _fdopen nie powinny być używane, gdy wymagana jest przenośność ANSI.

Przykład 1

Poniższy program otwiera dwa pliki. Używa fclose metody , aby zamknąć pierwszy plik i _fcloseall zamknąć wszystkie pozostałe pliki.

// 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

Przykład 2

Poniższy program tworzy plik (lub zastępuje go, jeśli istnieje), w trybie tekstowym, który ma kodowanie Unicode. Następnie zapisuje dwa ciągi w pliku i zamyka plik. Dane wyjściowe to plik o nazwie _wfopen_test.xml, który zawiera dane z sekcji danych wyjściowych.

// 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;
}

Zobacz też

We/Wy strumienia
Interpretacja sekwencji znaków wielobajtowych
fclose, _fcloseall
_fdopen, _wfdopen
ferror
_fileno
freopen, _wfreopen
_open, _wopen
_setmode
_sopen, _wsopen