Как прочитать файл конфигурации или создать его, если он отсутствует - PullRequest
2 голосов
/ 20 марта 2019

Как создать файл, но только если он еще не существует? Например ... Я хочу прочитать текстовый файл, но если он не существует, я хочу создать его с текстом по умолчанию.

Я могу легко создать файл с текстом по умолчанию. И я могу добавить или перезаписать его, если он уже существует.

Но если он уже содержит какой-то текст, я хочу ПРОЧИТАТЬ С него. НЕ НАПИСАТЬ. Как вы можете сделать с точечным файлом или файлом конфигурации, чтобы установить конфигурацию по умолчанию в случае, если файл отсутствует.

Это довольно просто с Python, но я пытаюсь сделать переход на C, и это более сложный, чем я ожидал.


Так что моя функция пока выглядит примерно так. Текст - это просто заполнитель для любого реального текста.

main() {
    FILE *fp;

    fp = fopen("./filename.txt", "w");
    fprintf(fp, "some default text\n");
    fclose(fp);
}

Так что просто для пояснения: если ./file.txt уже существует, его не следует записывать. Это должно быть прочитано с.

Когда я говорю «читать из», его можно распечатать на stdout или сохранить, например, в массиве, но это, вероятно, выходит за рамки вопроса.

Ответы [ 2 ]

4 голосов
/ 20 марта 2019

В вашем примере есть две основные ошибки:

  1. Вы не проверяете результат fopen, поэтому вы не знаете, был ли ваш файл успешно открыт (вот ключ к ответу).
  2. printf печатает прямо на stdout, и вы должны использовать fprintf для печати в файл конфигурации.

Я предлагаю следующее: попробуйте fopen ваш файл конфигурации (например, ./filename.txt) для r и проверьте результат этого вызова. После успешного завершения fopen верните FILE указатель на ваш существующий файл конфигурации. Если файл не существует, fopen возвращает NULL и значение errno равно ENOENT. В этом случае вы можете создать новый файл конфигурации и записать в него конфигурацию по умолчанию.

См. Раздел man 3 для соответствующих документов.

UPD

Вот PoC для предложения

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
    FILE *fp = fopen(".rc", "r");
    if (!fp)
        switch (errno) {
            case ENOENT:
                fprintf(stderr, "No config found, creating the default one\n");
                fp = fopen(".rc", "w");
                if (!fp) {
                    perror("Failed to create default config: ");
                    return EXIT_FAILURE;
                }
                /* write default config here */
                break;
            default:
                perror("Failed to open existing config: ");
                return EXIT_FAILURE;
        }

    /* read existing config here */
    return EXIT_SUCCESS;
}
0 голосов
/ 20 марта 2019

Используйте stat перед открытием файла. Если статистика успешна, то файл существует, если нет, проверьте ENOENT в errno.

Пример

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main()
{
    struct stat file_infos;
    char file_path[] = "/whatever"
    if (stat(file_path, &file_infos) != 0)
    {
        if (errno == ENOENT)
        {
            // Do whatever when the file wasn't found
        }
        else
        {
            // Error accessing the file, check the errno for more infos
        }
    }
    else
    {
        // File exists, do whatever you like with it.
    }
}

Наслаждайтесь:)

...