fopen_s、_wfopen_s
更新 : 2007 年 11 月
ファイルを開きます。これらの関数は、「CRT のセキュリティ強化」に説明されているように、fopen、_wfopen のセキュリティが強化されたバージョンです。
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
);
パラメータ
[出力] pFile
開かれたファイルへのポインタを受け取るファイル ポインタへのポインタ。[入力] filename
ファイル名。[入力] mode
アクセス許可の種類。
戻り値
正常終了した場合は 0 を返します。失敗した場合はエラー コードを返します。エラー コードの詳細については、「_doserrno、errno、_sys_errlist、および _sys_nerr」を参照してください。
エラー条件
pFile |
filename |
mode |
戻り値 |
pFile の内容 |
---|---|---|---|---|
NULL |
any |
any |
EINVAL |
変更なし |
any |
NULL |
any |
EINVAL |
変更なし |
any |
any |
NULL |
EINVAL |
変更なし |
解説
fopen_s および _wfopen_s で開かれたファイルは共有できません。ファイルを共有する必要がある場合には、適切な共有モード定数 (たとえば、読み取り/書き込み共有の場合は _SH_DENYNO) で _fsopen、_wfsopen を使用します。
fopen_s 関数は、filename で指定されたファイルを開きます。ワイド文字を扱う場合は、fopen_s ではなく _wfopen_s を使用します。_wfopen_s の場合、引数にはワイド文字列を指定します。引数の指定以外では、_wfopen_s と fopen_s の動作は同じです。
fopen_s は、実行時にファイル システムで有効なパスを受け取ります。UNC パス、および割り当てられたネットワーク ドライブを含むパスは、コードを実行するシステムが実行時に共有ネットワーク ドライブまたは割り当てられたネットワーク ドライブにアクセスする限り、fopen_s で受け取られます。実行時環境で使用できるドライブ、パス、またはネットワーク共有を判断されないように fopen_s のパスを構築する場合は、特に注意する必要があります。
これらの関数では、パラメータの検証が行われます。pFile、ファイル名、またはモードが null ポインタの場合には、「パラメータの検証」に説明されているように、これらの関数は無効なパラメータの例外を生成します。
ファイルでその他の操作を実行する前には、必ず戻り値をチェックして関数が成功したかどうかを確認します。エラーが発生すると、エラー コードが返され、グローバル変数errno が設定されます。詳細については、「errno、_doserrno、_sys_errlist、および _sys_nerr」を参照してください。
Visual C++ 2005 では、fopen_s> は Unicode のファイル ストリームをサポートします。必要なエンコーディングを指定するフラグは、新しいファイルを開いたり既存のファイルを上書きしたりすると、次のように fopen_s に渡されることがあります。
fopen_s(&fp, "newfile.txt", "rw, ccs=<encoding>");
encoding に指定できる値には、UNICODE、UTF-8、および UTF-16LE があります。ファイルが既に存在し、読み取り用または追加用に開かれる場合、バイト順マーク (BOM: Byte Order Mark) を使用して適切なエンコーディングが決定されます。フラグでエンコーディングを指定する必要はありません。実際、BOM で示されたようにフラグがファイルの種類と競合する場合、このフラグは無視されます。フラグは、BOM が表示されていない場合またはファイルが新しいファイルの場合のみ使用されます。fopen に指定される各種フラグとファイルで使用されるバイト順マークで使用されるモードを次の表に示します。
Flag および BOM に基づいて使用されるエンコーディング
フラグ |
BOM なし (または新しいファイル) |
BOM: UTF-8 |
BOM: UTF-16 |
---|---|---|---|
UNICODE |
ANSI |
UTF-8 |
UTF-16LE |
UTF-8 |
UTF-8 |
UTF-8 |
UTF-16LE |
UTF-16LE |
UTF-16LE |
UTF-8 |
UTF-16LE |
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 TYPE コマンドでは元の EOF マーカーまでのデータしか表示されず、ファイルに追加されたデータは表示されません。"a+" モードでは、ファイルへの追加の前に EOF マーカーが削除されます。追加が終了すると、MS-DOS の TYPE コマンドでファイル内すべてのデータが表示されます。Ctrl + Z EOF マーカーで終了するストリーム ファイルに追加するには、"a+" モードを使用する必要があります。
"r+"、"w+"、または "a+" のいずれかのアクセスの種類を指定すると、読み取りと書き込みの両方を行うことができます (ファイルは "更新" モードで開きます)。ただし、読み取りと書き込みを切り替える場合は、その前に fflush、fsetpos、fseek、または rewind のいずれかの関数を実行する必要があります。必要に応じて、fsetpos 関数または fseek 関数には現在位置を指定できます。
上記の値に加え、mode に次の文字を追加すると、改行文字の変換モードを指定できます。
- t
ファイルをテキスト (変換) モードで開きます。このモードでは、Ctrl + Z は入力時に EOF (EOF: end-of-file) 文字として解釈されます。"a+" を使用して読み取りおよび書き込みの両方のモードで開かれたファイルでは、fopen_s がファイル末尾に Ctrl + Z があるかどうかを確認し、削除できる場合は削除します。この処理が行われる理由は、CTRL+Z で終わるファイルの中身を fseek 関数および ftell 関数で移動するとき、ファイル末尾付近で fseek が正しく動作しないことがあるためです。
さらに、テキスト モードでは、復帰と改行の組み合わせは入力時に 1 つの改行に変換され、改行文字が出力時に復帰と改行の組み合わせに変換されます。Unicode のストリーム入出力関数が既定のテキスト モードで動作すると、入力元または出力先のストリームはマルチバイト文字のシーケンスと仮定されます。このため、Unicode ストリーム入力関数はマルチバイト文字をワイド文字に変換し、mbtowc 関数を呼び出した場合と同様の効果を得ます。同様の理由で、Unicode ストリーム出力関数は、wctomb 関数が呼び出されたかのように、ワイド文字をマルチバイト文字に変換します。
- b
ファイルをバイナリ (無変換) モードで開きます。キャリッジ リターンとライン フィードの変換は行われません。
t または b を mode に指定しないと、既定の変換モードは _fmode グローバル変数によって定義されます。t または b を引数の先頭に指定すると、エラーが発生して NULL が返されます。
Unicode およびマルチバイトのストリーム入出力におけるテキスト モードおよびバイナリ モードの使い方の詳細については、「テキスト モードとバイナリ モードのファイル入出力」および「テキスト モードとバイナリ モードの Unicode ストリーム入出力」を参照してください。
c
関連付けられた filename のコミット フラグを有効にして、fflush または _flushall のいずれかが呼び出された場合に、ファイル バッファの内容がディスクに直接書き込まれるようにします。n
関連付けられた filename のコミット フラグを "コミットなし" にリセットします。これは、既定の設定です。プログラムが COMMODE.OBJ にリンクされている場合、グローバル コミット フラグも上書きします。プログラムが明示的に COMMODE.OBJ にリンクされていない場合、グローバル コミット フラグの既定の設定は "コミットなし" です (「リンク オプション」参照)。N
ファイルが子プロセスによって継承されないように指定します。S
キャッシュがディスクからのシーケンシャル アクセスに最適化されるように指定します。ただし、シーケンシャル アクセスに限定されるわけではありません。R
キャッシュがディスクからのランダム アクセスに最適化されるように指定します。ただし、ランダム アクセスに限定されるわけではありません。T
ファイルを一時ファイルとして指定します。可能な場合、ファイルはディスクにフラッシュされません。D
ファイルを一時ファイルとして指定します。最後のファイル ポインタが閉じられると、ファイルは削除されます。ccs=ENCODING
このファイルに使用するコード化された文字セット (ANSI、UTF-8、UTF-16LE、および UNICODE) を指定します。このオプションは Visual C++ 2005 以降で使用できます。
fopen_s および _fdopen で使用される mode 文字列に有効な文字は、_open および _sopen で使用する oflag 引数に次のように対応しています。
mode 文字列の文字 |
_open/_sopen に相当する oflag 値 |
---|---|
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 ランタイム ライブラリのすべてのバージョン。
c、n、および t の各 mode オプションは、fopen_s および _fdopen の Microsoft 拡張機能です。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 )
{
int numclosed;
errno_t err;
// Open for read (will fail if file "crt_fopen_s.c" does not exist)
if( (err = fopen_s( &stream, "crt_fopen_s.c", "r" )) !=0 )
printf( "The file 'crt_fopen_s.c' was not opened\n" );
else
printf( "The file 'crt_fopen_s.c' was opened\n" );
// Open for write
if( (err = fopen_s( &stream2, "data2", "w+" )) != 0 )
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_s.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_s.c' was opened
The file 'data2' was opened
Number of files closed by _fcloseall: 1