Перейти к содержанию
  • Лента
  • Популярные
  • Последние
  • Теги
  • Пользователи
  • Сотрудничество
Свернуть
Логотип бренда
Категории
  1. Промышленный форум
  2. Категории
  3. ПO для чпу
  4. Работа с файлами в C: от открытия до закрытия

Работа с файлами в C: от открытия до закрытия

Запланировано Прикреплена Закрыта Перенесена ПO для чпу
1 Сообщения 1 Постеры 76 Просмотры 1 Отслеживают
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • kirilljsxK Не в сети
    kirilljsxK Не в сети
    kirilljsx
    Модератор
    написал в отредактировано
    #1

    Файлы - это то, без чего сложно представить любую серьезную программу. Ведь в реальности нам нужно не просто считать данные с клавиатуры и вывести на экран, а сохранить информацию, чтобы она осталась после завершения программы. Работа с файлами в C может показаться запутанной, но на самом деле это логично и понятно, если разобраться. И особенно это необходимо если мы работаем в промышленности и со станками ЧПУ.

    Работа с файлами строится на трех китах:

    • Открыть файл - сообщить операционной системе, что нам нужен доступ к файлу (для чтения, записи или того и другого)
    • Выполнить операции - читать или записывать данные
    • Закрыть файл - освободить ресурсы и сохранить изменения
      ​

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

    Объект FILE и функция fopen

    Для работы с файлами в C используется структура FILE. Это абстрактный объект, который хранит всю информацию о файловом потоке: указатель на буфер, позицию в файле, индикаторы состояния.

    FILE *file;
    file = fopen("test.txt", "w");
    

    Функция fopen() принимает два параметра:

    • Путь к файлу - может быть абсолютным (C:/projects/data.txt) или относительным (data.txt)
    • Режим доступа - строка, определяющая, что мы собираемся делать с файлом

    Режимы открытия файлов
    Режимы доступа определяют, как мы будем работать с файлом:

    Режим Описание
    “r” Чтение. Файл должен существоватьlearnc+1​
    “w” Запись. Если файл существует — его содержимое удаляетсяlearnc+1​
    “a” Добавление в конец. Файл создаётся, если не существовалlearnc​
    “r+” Чтение и запись. Файл должен существоватьlearnc​
    “w+” Чтение и запись. Старое содержимое теряетсяlearnc​
    “a+” Чтение и добавление в конецlearnc​

    Для бинарных файлов добавляем букву b: "rb", "wb", "ab+" и так далее. В текстовом режиме можно использовать "rt", "wt", хотя по умолчанию и так используется текстовый режим.

    Простой пример: запись и чтение

    Перед тем как приступить к написанию новой программы надеюсь вы уже знаете как делать компиляцию, да и в целом познакомились с базовыми правилами Си. Если нет, то лучше прочитайте и пройдитесь по основам тут. Этих базовых знаний будет не достаточно, материал скорее подготовлен для более опытных программистов чем для новичков, но Вам в любом случае рано или поздно придется столкнуться с файлами.

    Продолжаем, теперь давайте запишем строку в файл, а потом считаем ее обратно:

    #include <stdio.h>
    
    int main() {
        FILE *file;
        char buffer[128];
        
        // Записываем данные
        file = fopen("test.txt", "w");
        fprintf(file, "Hello, World!");
        fclose(file);
        
        // Читаем данные
        file = fopen("test.txt", "r");
        fgets(buffer, 127, file);
        printf("%s", buffer);
        fclose(file);
        
        return 0;
    }
    

    Здесь fprintf() и fgets() работают точно так же, как printf() и gets(), только первым параметром передаётся указатель на файл.

    Обработка ошибок при открытии

    Если файл не удалось открыть, fopen() вернет NULL. Это может случиться по разным причинам: файла не существует, нет прав доступа, диск переполнен. Проверка на ошибки обязательна:

    file = fopen("data.txt", "r");
    if (file == NULL) {
        printf("Ошибка открытия файла!\n");
        exit(1);
    }
    

    При работе с несколькими файлами важно закрывать уже открытые файлы, если один из них не открылся:

    inputFile = fopen("input.txt", "r");
    if (inputFile == NULL) {
        printf("Ошибка открытия input.txt\n");
        exit(1);
    }
    
    outputFile = fopen("output.txt", "w");
    if (outputFile == NULL) {
        printf("Ошибка открытия output.txt\n");
        if (inputFile != NULL) {
            fclose(inputFile);  // Закрываем первый файл!
        }
        exit(1);
    }
    

    Буферизация: почему данные не сразу попадают в файл

    Когда мы записываем данные в файл, они сначала попадают в буфер - специальную область памяти. Данные из буфера записываются в файл:

    • Когда буфер заполнен
    • Когда файл закрывается функцией fclose()
    • Когда программа завершается успешно
    • Когда мы явно вызываем fflush(file)

    Пример с принудительной очисткой буфера:

    FILE *file = fopen("test.txt", "w");
    char c;
    
    do {
        c = getch();
        fprintf(file, "%c", c);
        fprintf(stdout, "%c", c);
        fflush(file);  // Данные сразу записываются в файл
    } while(c != 'q');
    
    fclose(file);
    

    Без вызова fflush() данные останутся в буфере до тех пор, пока он не заполнится или файл не закроется.

    Проблема с feof()

    Функция feof() проверяет, достигнут ли конец файла. Звучит полезно, но есть подвох: часто она работает некорректно и дублирует последний считанный элемент:

    // Плохой пример последний символ выведется дважды!
    while (!feof(input)) {
        fscanf(input, "%c", &c);
        fprintf(stdout, "%c", c);
    }
    

    Правильное решение - использовать возвращаемое значение функций чтения. Например, fscanf() возвращает количество успешно прочитанных элементов:

    // Правильный пример
    while (fscanf(input, "%c", &c) == 1) {
        fprintf(stdout, "%c", c);
    }
    

    Или можно использовать EOF для посимвольного чтения:

    int ch;  // int, а не char!
    while ((ch = fgetc(input)) != EOF) {
        printf("%c", ch);
    }
    

    Обратите внимание: переменная должна быть типа int, потому что EOF - это целочисленная константа, а не символ.


    Стандартные потоки: stdin, stdout, stderr

    В любой программе автоматически открываются три стандартных потока:

    • stdin - стандартный ввод (клавиатура)
    • stdout - стандартный вывод (консоль)
    • stderr - поток вывода ошибок (тоже консоль, но можно перенаправить отдельно)

    Это обычные файловые потоки типа FILE*, с которыми можно работать через fprintf() и fscanf():

    int a, b;
    fprintf(stdout, "Введите два числа\n");
    fscanf(stdin, "%d", &a);
    fscanf(stdin, "%d", &b);
    
    if (b == 0) {
        fprintf(stderr, "Ошибка: деление на ноль\n");
    } else {
        fprintf(stdout, "%.3f\n", (float)a / (float)b);
    }
    

    Практические примеры

    Копирование файла посимвольно:

    FILE *origin = fopen("input.txt", "r");
    FILE *copy = fopen("output.txt", "w");
    
    if (origin == NULL || copy == NULL) {
        printf("Ошибка открытия файла\n");
        if (origin) fclose(origin);
        if (copy) fclose(copy);
        exit(1);
    }
    
    int ch;
    while ((ch = fgetc(origin)) != EOF) {
        fputc(ch, copy);
    }
    
    fclose(origin);
    fclose(copy);
    

    Поиск максимального числа в файле:

    FILE *input = fopen("numbers.txt", "r");
    if (input == NULL) {
        printf("Ошибка открытия файла\n");
        exit(1);
    }
    
    int num, maxn = INT_MIN;
    while (fscanf(input, "%d", &num) == 1) {
        if (num > maxn) {
            maxn = num;
        }
    }
    
    printf("Максимальное число: %d\n", maxn);
    fclose(input);
    

    Подсчет строк в файле:

    int countLines(const char *filename) {
        FILE *f = fopen(filename, "r");
        if (f == NULL) return -1;
        
        int lines = 0;
        int ch;
        
        while ((ch = fgetc(f)) != EOF) {
            if (ch == '\n') {
                lines++;
            }
        }
        
        fclose(f);
        return lines;
    }
    

    Резюмируем

    Работа с файлами в C требует дисциплины: нужно всегда проверять результат fopen(), правильно выбирать режим доступа и обязательно закрывать файлы. Понимание буферизации помогает избежать потери данных. А правильное использование функций чтения вместо feof() избавляет от головной боли с дублированием последних элементов.

    1 ответ Последний ответ
    0

    Здравствуйте! Похоже, вас заинтересовал этот пост, но у вас ещё нет аккаунта.

    Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.

    С вашими комментариями этот пост мог бы стать ещё лучше 💗

    Зарегистрироваться Войти

    • kirilljsxK

      Парсинг DNC-файлов Fanuc через Python для подсчета нормо-часов и оптимизации плана

      Отслеживается Игнорируется Запланировано Прикреплена Закрыта Перенесена ПO для чпу fanuc python dnc
      1
      1
      0 Голоса
      1 Сообщения
      16 Просмотры
      Нет ответов
    • kirilljsxK

      Обслуживание станков с ЧПУ: ТО и ремонт для надежной работы

      Отслеживается Игнорируется Запланировано Прикреплена Закрыта Перенесена ПO для чпу чпу то станков ремонт
      1
      0 Голоса
      1 Сообщения
      24 Просмотры
      Нет ответов
    • kirilljsxK

      Безопасность при работе с ЧПУ: ключевые меры защиты оператора

      Отслеживается Игнорируется Запланировано Прикреплена Закрыта Перенесена ПO для чпу чпу безопасность техника безопасности cnc защита
      1
      0 Голоса
      1 Сообщения
      17 Просмотры
      Нет ответов
    • kirilljsxK

      Система ЧПУ: устройство и принцип работы станка с числовым управлением

      Отслеживается Игнорируется Запланировано Прикреплена Закрыта Перенесена ПO для чпу чпу устройство принцип работы
      1
      0 Голоса
      1 Сообщения
      20 Просмотры
      Нет ответов
    • kirilljsxK

      Режимы работы Siemens Sinumerik: JOG, MDA, AUTO для ЧПУ станков

      Отслеживается Игнорируется Запланировано Прикреплена Закрыта Перенесена ПO для чпу sinumerik режимы чпу jog auto
      1
      0 Голоса
      1 Сообщения
      42 Просмотры
      Нет ответов
    • kirilljsxK

      Формат OBJ: структура файла, примеры и использование в 3D-моделировании

      Отслеживается Игнорируется Запланировано Прикреплена Закрыта Перенесена ПO для чпу obj 3d-модели чпу
      1
      0 Голоса
      1 Сообщения
      21 Просмотры
      Нет ответов
    • TimT

      Работа со строками в C: Полное руководство

      Отслеживается Игнорируется Запланировано Прикреплена Закрыта Перенесена ПO для чпу
      1
      1 Голоса
      1 Сообщения
      58 Просмотры
      Нет ответов
    • TimT

      Указатели в C и работа с памятью: Полное руководство

      Отслеживается Игнорируется Запланировано Прикреплена Закрыта Перенесена ПO для чпу
      1
      1 Голоса
      1 Сообщения
      79 Просмотры
      Нет ответов

    Категории

    • Главная
    • Новости
    • Объявления
    • ПО и ЧПУ
    • Обсуждение

    Контакты

    • Сотрудничество
    • forum@investsteel.ru

    © 2022 - 2026 InvestSteel, Inc. Все права защищены.

    Политика конфиденциальности
    • Войти

    • Нет учётной записи? Зарегистрироваться

    • Войдите или зарегистрируйтесь для поиска.
    • Первое сообщение
      Последнее сообщение
    0
    • Лента
    • Популярные
    • Последние
    • Теги
    • Пользователи
    • Сотрудничество