Open a file. More secure versions of these functions are available; see fopen_s, _wfopen_s.
FILE *fopen( const char *filename, const char *mode ); FILE *_wfopen( const wchar_t *filename, const wchar_t *mode );
Each of these functions returns a pointer to the open file. A null pointer value indicates an error. If filename or mode is NULL or an empty string, these functions trigger the invalid parameter handler, as described in Parameter Validation. If execution is allowed to continue, these functions return NULL and set errno to EINVAL.
See _doserrno, errno, _sys_errlist, and _sys_nerr for more information on these, and other, error codes.
More secure versions of these functions exist, see fopen_s, _wfopen_s.
The fopen function opens the file specified by filename. _wfopen is a wide-character version of fopen; the arguments to _wfopen are wide-character strings. _wfopen and fopen behave identically otherwise. Simply using _wfopen has no effect on the coded character set used in the file stream.
fopen will accept paths that are valid on the file system at the point of execution; UNC paths and paths involving mapped network drives are accepted by fopen as long as the system executing the code has access to the share or mapped network drive at the time of execution. Special care must be taken when constructing paths for fopen to avoid making assumptions about available drives, paths or network shares in the execution environment.
Always check the return value to see if the pointer is NULL before performing any further operations on the file. If an error occurs, the global variableerrno is set and may be used to get specific error information. For further information, see errno.
In Visual C++ 2005, fopen supports Unicode file streams. A flag specifying the desired encoding may be passed to fopen when opening a new file or overwriting an existing file, like this:
fopen("newfile.txt", "rw, ccs=<encoding>");
Allowed values of the encoding include UNICODE, UTF-8, and UTF16-LE. If the file is already in existence and is opened for reading or appending, the Byte Order Mark (BOM) is used to determine the correct encoding. It is not necessary to specify the encoding with a flag. In fact, the flag will be ignored if it conflicts with the type of the file as indicated by the BOM. The flag is only used when no BOM is present or if the file is a new file. The following table summarizes the modes used in for various flags given to fopen and Byte Order Marks used in the file.
|
Flag |
No BOM (or new file) |
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 |
If mode is "a, ccs=<encoding>", fopen will first try to open the file with both read and write access. If it succeeds, it will read the BOM to determine the encoding for this file; however, if it fails, it will use the default encoding for the file. In either case, fopen will then re-open the file with write-only access. (This applies to mode a only, not a+.)
|
TCHAR.H routine |
_UNICODE & _MBCS not defined |
_MBCS defined |
_UNICODE defined |
|---|---|---|---|
|
_tfopen |
fopen |
fopen |
_wfopen |
The character string mode specifies the type of access requested for the file, as follows:
When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file. The file pointer can be repositioned using fseek or rewind, but is always moved back to the end of the file before any write operation is carried out. Thus, existing data cannot be overwritten.
The "a" mode does not remove the EOF marker before appending to the file. After appending has occurred, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file. The "a+" mode does remove the EOF marker before appending to the file. After appending, the MS-DOS TYPE command shows all data in the file. The "a+" mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.
When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for "update"). However, when you switch from reading to writing, the input operation must encounter an EOF marker. If there is no EOF, you must use an intervening call to a file positioning function. The file positioning functions are fsetpos, fseek, and rewind. When you switch from writing to reading, you must use an intervening call to either fflush or a file positioning function.
In addition to the above values, the following characters can be included in mode to specify the translation mode for newline characters:
Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters (as if by a call to the mbtowc function). For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters (as if by a call to the wctomb function).
If t or b is not given in mode, the default translation mode is defined by the global variable _fmode. If t or b is prefixed to the argument, the function fails and returns NULL.
For more information about using text and binary modes in Unicode and multibyte stream-I/O, see Text and Binary Mode File I/O and Unicode Stream I/O in Text and Binary Modes.
Valid characters for the mode string used in fopen and _fdopen correspond to oflag arguments used in _open and _sopen, as follows.
|
Characters in mode string |
Equivalent oflag value for _open/_sopen |
|---|---|
|
a |
_O_WRONLY | _O_APPEND (usually _O_WRONLY | _O_CREAT | _O_APPEND) |
|
a+ |
_O_RDWR | _O_APPEND (usually _O_RDWR | _O_APPEND | _O_CREAT ) |
|
r |
_O_RDONLY |
|
r+ |
_O_RDWR |
|
w |
_O_WRONLY (usually _O_WRONLY | _O_CREAT | _O_TRUNC) |
|
w+ |
_O_RDWR (usually _O_RDWR | _O_CREAT | _O_TRUNC) |
|
b |
_O_BINARY |
|
t |
_O_TEXT |
|
c |
None |
|
n |
None |
|
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 |
If you are using rb mode, won't need to port your code, and expect to read a lot of the file and/or don't care about network performance, memory mapped Win32 files might also be an option.
|
Function |
Required header |
|---|---|
|
fopen |
<stdio.h> |
|
_wfopen |
<stdio.h> or <wchar.h> |
For additional compatibility information, see Compatibility in the Introduction.
The c, n, t,S,R,T andD mode options are Microsoft extensions for fopen and _fdopen and should not be used where ANSI portability is desired.
This program opens two files. It usesfclose to close the first file and _fcloseall to close all remaining files.
// 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 );
}
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. The output is a file named _wfopen_test.xml, which should contain the data from the output section.
// 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;
}
Reference
A few comments about the Unicode BOM (Byte-Order Mark) handling.
- The C-Runtime library (CRT) will not perform any BOM handling if you do not specify a ccs= encoding. This means that backwards compatibility is retained because the CRT does not perform any behind-the-scenes processing if you don't ask it to.
- The BOM calls must be used with wide-character read/write functions. This means that you'll get an assertion if you open the file with ccs=utf-8 and then try to use fgets to read the data. Note that you can mix single/multibyte calls (such as fopen) with wide-character calls (such as fgetws).
- Most BOM formats are not supported. For example, UTF-7, UTF-32 and especially UCS-16 big-endian are not handled.
- If you specify a specify a ccs= encoding, then the BOM will be automatically removed from the data stream. However, you need to be careful of file positioning calls such as fseek and rewind because the bom will only be skipped when the file is first opened. For example, if you do fopen, fread, rewind, fread, then the second fread will read the BOM and the first fread will not.
- The file encoding is respected when writing, so the number of characters actually written may be lesser or greater than the buffer size you wrote.
- If you open the file in binary mode, then any ccs= specification will be ignored and no BOM handling will be performed.