Раздел «Язык Си».UsingFiles:

Работа с файлами

Рассмотрим методы, с помощью которых можно создавать файлы и писать в них данные, и читать данные из существующих файлов.

Создание файлов

#include <stdio.h>
int main() { 
    FILE *f; 
    f = fopen("name.txt", "w"); 
    // ... работа с файлом
    fclose(f);
}
Эта программа создает файл "name.txt" в текущей директории. Если этот файл уже там присутствует, то она очищает его (обнуляет, то есть делает его пустым).

Первый аргумент у функции fopen — это путь к файлу (имя файла)

Второй аргумент — это спецификация режима, в котором будет открыт файл:

При успешном завершении fopen возвращают указатель FILE. Иначе возвращается NULL, а в глобальную переменную errno записывается код ошибки.

Чтение и запись

/* Program: files.c
   Build me with
     gcc -o files files.c
*/
#include <stdio.h>
int main() { 
  FILE *f_in, *f_out;
  f_in = fopen("in.txt", "r");
  f_out = fopen("out.txt", "w+");
  if (f_in == NULL && f_out == NULL) {
      fprintf (stderr, "Can't open one of two files\n");
  }
  fscanf (f_in, "%d%d", &a, &b);
  fprintf (fout, "%d", a + b);
  fclose (f_in);
  fclose (f_out);

Вопросы и задания

Выдержка из страницы помощи по fopen

Наберите команду

bash$ man 3 fopen
и вы увидете описание функции fopen

Вот выдержка из этого описания, касаемая режимов открывания файлов (второй аргумент):

Чтение и запись (примечание редактора) - корректная обработка ошибок

В коде, представленном в разделе Чтение и запись проанализируйте:

Некоторые стандартные функции языка С, если не могут сделать некоторое действие, например, открыть файл, пишут номер ошибки в глобальную переменную errno . Выводить в виде сообщения об ошибке открытия файла имя файла и номер ошибки - негуманно. Пользователи не обязаны заучивать коды ошибок. Более того, на разных операционных системах разные числа кодируют разные ошибки, и одна и та же ошибка (нет файла) кодируется в разных ОС разными числами.

Правильнее писать системное сообщение об ошибке. Для этого используют стандартную функцию языка С void perror(const char *s), которая печатает сначала переданную в параметре строку, потом через двоеточие сообщение об ошибке, номер которой хранится в errno.

Заметим, что если последняя вызываемая стандартная функция отработала без ошибок, она не обязана сбрасывать значение errno в состояние "без ошибок" и в этой переменной может хранится номер ошибки, который записала другая функция.

Не все функции изменяют значение errno в случае ошибки. Обычно это указывается в справке по функции.

Перепишем код чтения и записи в файл с диагностикой ошибок при открытии файлов.

/* Program: files.c
   Build me with
     gcc -o files files.c
*/
#include <stdio.h>
#include <error.h>       // чтобы заработал perror
int main() { 
  FILE *f_in = NULL, *f_out = NULL;
  f_in = fopen("in.txt", "r");
  if (f_in == NULL) {
      perror("in.txt");  // печатаем ошибку открытия файла на чтение, быть может его нет; или файл есть, а у вас нет прав на чтение файла
      return 7;          // даже если тесты проверяющей системой не показаны, код возврата в тесте показан всегда
  }
  f_out = fopen("out.txt", "w+");
  if (f_out == NULL) {
      perror("out.txt"); // если файла нет, то его создадут. А если нет прав создать этот файл? Тогда получим диагностику, что не хватает прав на создание
      fclose(f_in);        // хороший тон - закрыть уже открытые нами потоки
      return 8;          // даже если тесты проверяющей системой не показаны, код возврата в тесте показан всегда
  }

  fscanf (f_in, "%d%d", &a, &b);
  fprintf (fout, "%d", a + b);

  fclose (f_in);
  fclose (f_out);

-- ArtemVoroztsov - 24 Mar 2005