Функция fopen() открывает поток и связывает с этим потоком определенный файл. Затем она возвращает указатель этого файла. Чаще всего под файлом подразумевается дисковый файл. Прототип функции fopen() такой:
FILE* fopen (const char *имя_файла, const char *режим_доступа);
где первый параметр имя_файла – это указатель на строку символов, представляющую собой допустимое имя файла, которое может также включать путь к этому файлу, а второй параметр режим_доступа определяет, каким образом файл будет открыт. В таблице 6.2 показаны режимы работы с файлом.
Таблица 6.2. Режимы работы с файлом
Режим | Что означает |
r | Открыть текстовый файл для чтения |
w | Создать текстовый файл для записи |
a | Добавить в конец текстового файла |
rb | Открыть двоичный файл для чтения |
wb | Создать двоичный файл для записи |
ab | Добавить в конец двоичного файла |
r+ | Открыть текстовый файл для чтения/записи |
w+ | Создать текстовый файл для чтения/записи |
a+ | Добавить в конец текстового файла или создать текстовый файл для чтения/записи |
r+b | Открыть двоичный файл для чтения/записи |
w+b | Создать двоичный файл для чтения/записи |
a+b | Добавить в конец двоичного файла или создать двоичный файл для чтения/записи |
Хотя название большинства файловых режимов объясняет их смысл, сделаем некоторые дополнения. Если попытаться открыть файл только для чтения, а он не существует, то работа fopen() завершится отказом. А если попытаться открыть файл в режиме дополнения, а сам этот файл не существует, то он просто будет создан. Более того, если файл открыт в режиме дополнения, то все новые данные, которые записываются в него, будут добавляться в конец файла. Содержимое, которое хранилось в нем до открытия (если только оно было), изменено не будет. Далее, если файл открывают для записи, но выясняется, что он не существует, то он будет создан. А если он существует, то содержимое, которое хранилось в нем до открытия, будет утеряно, причем будет создан новый файл.
Разница между режимами r+ и w+ состоит в том, что если файл не существует, то в режиме открытия r+ он создан не будет, а в режиме w+ все произойдет наоборот: файл будет создан. Более того, если файл уже существует, то открытие его в режиме w+ приведет к утрате его содержимого, а в режиме r+ оно останется нетронутым.
Динамическая переменная с информацией о файле, которую создаёт и инициализирует функция fopen() и на которую указывает файловая переменная (или указатель файла), имеет следующую структуру:
typedef struct {
unsigned char *curp; // Current active pointer
unsigned char *buffer; // Data transfer buffer
int level; // Fill/Empty level of buffer
int bsize; // Buffer size
unsigned short istemp; // Temporary file indicator
unsigned short flags; // File status flags
wchar_t hold; // Ungetc char if no buffer
char fd; // File descriptor
unsigned char token; // Used for validity checking
} FILE;
В функции fopen() можно задать конкретное имя файла или предоставить выбор имени пользователю.
1) задание конкретного имени файла:
FILE *fp;
fp = fopen ("file.txt", "wt");
2) имя файла выбирает пользователь:
FILE *fp;
char FileName[16];
printf ("\n Enter file name ");
scanf ("%s", FileName); // или scanf("%s", &FileName[0]);
fp = fopen (FileName, "wt");
Функция fopen() возвращает указатель файла. Никогда не следует изменять значение этого указателя в программе. Если при открытии файла происходит ошибка, то fopen() возвращает пустой (NULL) указатель.
Хотя предыдущий код технически правильный, но его обычно пишут немного по-другому:
FILE *fp;
fp = fopen("file.txt", "wt");
if (fp == NULL) {
printf ("\n Error opening the file \n");
exit(1);
}
Этот метод помогает обнаружить любую ошибку при открытии файла, например, защиту от записи или полный диск, причем обнаружить еще до того, как программа попытается в этот файл что-либо записать. Вообще говоря, всегда нужно вначале получить подтверждение, что функция fopen() выполнилась успешно, и лишь затем выполнять с файлом другие операции.
Максимальное число одновременно открытых файлов определяется константой FOPEN_MAX. Это значение не меньше 8, но чему оно точно равняется – это должно быть написано в документации по компилятору.