fopen_s、_wfopen_s
開啟檔案。 這些版本的 fopen、 _wfopen 中所述有安全性增強功能, 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
);
參數
[] outpFile
檔案指標會接收到開啟的檔案指標的指標。[in]filename
檔名。[in]mode
許可的存取類型。
傳回值
如果成功 ;,零 在失敗的錯誤碼。 請參閱errno、_doserrno、_sys_errlist 和 _sys_nerr如需有關這些錯誤碼。
錯誤條件
pFile |
filename |
mode |
傳回值 |
內容pFile |
---|---|---|---|---|
NULL |
任何 |
任何 |
EINVAL |
未變更 |
任何 |
NULL |
任何 |
EINVAL |
未變更 |
任何 |
任何 |
NULL |
EINVAL |
未變更 |
備註
藉由開啟檔案的fopen_s和 _wfopen_s不是可共用。 如果您需要的檔案是可共用,請使用_fsopen、_wfsopen與適當的共用模式常數 — 例如, _SH_DENYNO的讀取/寫入共用。
fopen_s函式會開啟的檔案,由指定 filename. _wfopen_s寬字元版本的 fopen_s; 引數以_wfopen_s是寬字元字串。 _wfopen_s和 fopen_s運作方式完全相同否則。
fopen_s接受在執行 ; 在檔案系統有效的路徑 UNC 路徑以及牽涉到對應的網路磁碟機的路徑會被接受的 fopen_s,只要系統執行程式碼有共用的存取權,或一次執行的對應網路磁碟機。 當您建構路徑 fopen_s、 不做假設有關可用的磁碟機,路徑,或在執行環境中的網路共用。 您可以使用正斜線 (/) 或反斜線 (\) 做為目錄分隔符號在路徑中。
這些函式會驗證它們的參數。 如果 pFile, filename,或 mode是一個 null 指標,如所述,這些函式會產生不正確的參數例外狀況, 參數驗證.
一定要檢查傳回值,以查看函式是否成功之前執行任何進一步的作業,在檔案上。 如果發生錯誤時,傳回的錯誤碼和全域變數errno設有。 如需詳細資訊,請參閱 errno、_doserrno、_sys_errlist 和 _sys_nerr.
Unicode 支援
fopen_s支援 Unicode 的檔案資料流。 若要開啟新的或現有的 Unicode 檔,請傳遞ccs旗標,指定您想要的編碼, fopen_s:
fopen_s(&fp, "newfile.txt", "rw, ccs=encoding");
允許的值encoding的 UNICODE, UTF-8,和 UTF-16LE. 如果那里不指定任何值時, encoding, fopen_s使用 ANSI 編碼方式。
如果檔案已經存在,而且開啟進行讀取或附加,位元組順序標記 (BOM),如果有的話,在檔案中,會判斷編碼方式。 BOM 的編碼方式的優先權會高於的編碼方式所指定的ccs旗標。 ccs編碼方式只適用於沒有 BOM 是存在,或如果檔案是新的檔案。
注意事項 |
---|
BOM 偵測只適用於 Unicode 模式 ; 在開啟的檔案 也就藉由傳遞ccs旗標。 |
下表摘要模式的各種ccs旗標,指定給 fopen_s,以及在檔案中的位元組順序標記。
編碼方式使用根據 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 |
開啟的檔案以 Unicode 模式寫入的有 BOM,會自動寫入其中。
如果mode是 「a, ccs=<encoding>」, fopen_s第一次嘗試開啟檔案以讀取和寫入存取權。 如果成功的話,此函式會讀取 BOM 來判斷檔案 ; 的編碼方式 如果不成功,則函式會使用檔案的預設編碼方式。 在任一情況, fopen_s再重新開啟的檔案具有唯寫存取權。 (這適用於a模式唯一的不 a+。)
泛用文字常式對應
TCHAR。H 常式 |
_UNICODE & 未定義的 _MBCS |
定義的 _MBCS |
定義 _unicode 之後 |
---|---|---|---|
_tfopen_s |
fopen_s |
fopen_s |
_wfopen_s |
字元字串mode指定的如下所示要求檔案的存取種類。
"r"
開啟進行讀取。 如果檔案不存在或找不到, fopen_s呼叫失敗。"w"
開啟空白檔案進行寫入。 如果檔案存在,其內容已終結。"a"
會開啟以進行寫入的檔案 (附加) 而不移除 EOF 標記之前將新的資料寫入至檔案結尾。 如果不存在,請建立該檔案。"r+"
會開啟以進行讀取和寫入。 (檔案必須存在)。"w+"
開啟空白檔案來讀取和寫入。 如果檔案存在,其內容已終結。"a+"
開啟用於讀取和附加。 新的資料寫入檔案,並撰寫完成之後,就會還原 EOF 標記之前,附加作業包括 EOF 標記移除。 如果不存在,請建立該檔案。
藉由開啟檔案時"a"或 "a+"存取型別,所有寫入作業就會發生在檔案結尾處。 檔案指標可以藉由重新調整位置fseek或 rewind,但它一律移至檔案結尾之前任何寫入作業,因此無法覆寫現有的資料會論及。
"a"模式並不會移除 EOF 標記之前附加至檔案。 附加之後,[MS-DOS 類型] 指令只會顯示原始 EOF 標記資料和附加至該檔案不是任何資料。 "a+"模式不會移除 EOF 標記之前附加至檔案。 之後將附加,MS-DOS 類型] 指令會顯示所有資料檔案中。 "a+"模式,才能將附加至資料流的檔案,便會終止使用 CTRL + Z EOF 標記。
當 "r+", "w+",或 "a+"指定存取類型、 允許讀取和寫入。 (該檔案就稱為屬於開啟以 「 更新 」)。 不過,當您切換正在讀取的書寫時,輸入的作業必須遇到 EOF 標記。 如果沒有 EOF,您必須使用檔案位置的函式呼叫的中間。 檔案位置的函式是 fsetpos, fseek,和 rewind. 當您切換寫入讀取時,您必須使用其中的多餘呼叫fflush或檔案位置的函式。
除了上述的值,可以包含下列字元在mode來指定新行字元的轉譯模式:
- t
在文字中的開啟 (轉譯) 模式。 在此模式中,CTRL + Z 會解譯為輸入的檔案結尾字元。 在檔案開啟進行讀取/寫入與 "a+", fopen_s檢查 CTRL + Z 結尾的檔案並移除它,如果可能的話。 這是因為使用fseek和 ftell以 CTRL + Z,可能會造成檔案內移動 fseek檔案的結尾附近的不當行為。
此外,在文字模式中,換行字元 return–linefeed 組合會轉譯成輸入時,單一等等,換行字元會轉譯為在輸出上的換行字元 return–linefeed 組合。 當 Unicode 資料流 i/o 函式運作以文字模式 (預設)、 來源或目的端資料流會被假設為多位元組字元序列。 因此,Unicode 資料流輸入函式多位元組字元轉換為寬字元 (如如果呼叫mbtowc函式)。 基於相同的理由,Unicode 資料流輸出函式將寬字元轉換為多位元組字元 (如如果呼叫wctomb函式)。
- b
開啟以二進位 (未轉譯) 模式。 涉及歸位和換行字元的轉譯將被抑制。
如果t或 b不列在 mode、 預設轉譯模式定義的全域變數 _fmode。 如果t或 b引數、 函式失敗,且傳回有前置 NULL.
如需有關如何使用文字和二進位模式 Unicode 並使用多位元組資料流 i/o 的詳細資訊,請參閱文字和二進位模式檔案 I/O 和文字和二進位模式中的 Unicode 資料流 I/O。
c
啟用相關聯的認可旗標 filename,讓檔案緩衝區的內容將直接寫入磁碟中如果有任一 fflush或 _flushall稱為。n
重設相關聯的認可旗標filename為 「 無認可 」。 這是預設值。 如果您連結您的程式與 COMMODE.OBJ,它也會覆蓋全域認可旗標。 全域認可旗標預設值是"沒有認可" 除非您明確地連結您的程式與 COMMODE。OBJ (請參閱 連結選項)。N
指定檔案並未繼承給子處理程序。S
指定的最佳化,但不是限於,循序存取從磁碟快取。R
指定的最佳化,但不是限於,隨機存取從磁碟快取。T
指定暫存檔案。 如果可能的話,沒有轉存到磁碟。D
指定暫存檔案。 當最後一個檔案指標已關閉,它會被刪除。ccs=ENCODING
指定要用於此檔案中的 (utf-8、 UTF 16LE 和 UNICODE) 的硬式編碼的字元集。 離開這未指定是否您想在 ANSI 編碼方式。
有效字元為mode字串用 fopen_s和 _fdopen對應到 oflag引數中使用 _ 開啟 和 _sopen、,如下所示。
模式字串中的字元 |
對等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 |
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 檔案也可能是一個選項。
需求
函式 |
所需的標頭 |
---|---|
fopen_s |
< > stdio.h |
_wfopen_s |
< > stdio.h 或者 < wchar.h > |
其他相容性資訊,請參閱相容性在簡介中。
程式庫
所有版本的 C 執行階段程式庫。
c, n,和 t mode選項是 Microsoft 擴充功能的 fopen_s和 _fdopen,不應該使用 ANSI 的可攜性所需的位置。
範例
// 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 );
}