如果文件没有退出,则用C创建和写入

时间:2018-04-29 15:52:44

标签: c file if-statement fopen fwrite

如果它不存在,我只想写" null" s。如果它存在,我会写书名等不是空的。所以我尝试了这段代码。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 30

int main() {
    FILE * shelfFile;
    //if file doesn't exist
    char start[MAX] = "NULL";
    if (!(shelfFile = fopen("shelf.txt", "r"))) {
        shelfFile = fopen("shelf.txt", "w");
        printf("In if block\n");
        fwrite(start, sizeof(char), MAX, shelfFile);
        fwrite("\n", sizeof(char), 1, shelfFile);
    }   
    fclose(shelfFile);

    system("PAUSE");
    return 0;
}

当我运行此代码时,文件尚未创建,printf也不起作用。如果代码阻止,它很快就不会进入。这有什么问题?

2 个答案:

答案 0 :(得分:0)

只需打开文件一次,即可进行书写(即"w"模式)。如果该文件不存在,则将创建该文件;如果存在,其内容将在开放时销毁。

有关详细信息,请参阅此fopen这个方便的表格。

答案 1 :(得分:0)

如果你想坚持使用标准C,那么Acorn的答案就是现实。据我所知,测试文件是否存在会降级为特定于操作系统的API。

在Windows上,您可以编写函数来测试文件是否存在,方法是将文件名传递给GetFileAttributesFunction here。一旦你有了这个,你所要做的就是编写函数来有条件地创建文件(如果文件尚不存在)。

#include <Windows.h>

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

void createFile(const char *filename) {
    const HANDLE newFile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);

    if (newFile == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "[Error]: Failed to open file: %s\n", filename);

        exit(EXIT_FAILURE);
    }
}

int FileExists(const char *filename) {
    const DWORD fileAttributes = GetFileAttributes(filename);

    if (fileAttributes == 0xFFFFFFFF)
        return 0;

    return 1;
}

void ConditionallyCreateFile(const char *filename) {
    if (!FileExists(filename))
        createFile(filename);
}


int main()
{
    const char *filename = "test-file.txt";
    printf("File exists: %d\n", FileExists(filename));
    ConditionallyCreateFile(filename);
    printf("File exists: %d\n", FileExists(filename));

    return EXIT_SUCCESS;
}

当我第一次运行代码时,这是输出:

File exists: 0
File exists: 1

然后第二次:

File exists: 1
File exists: 1

尽管如此,我会指出,如果你使用的是Win32 API,你几乎肯定会使用Microsoft编译器,所以你可以用C ++编写相同的代码,我建议这样做。这就是它的样子:

#include <Windows.h>

#include <iostream>
#include <iomanip>
#include <string>

namespace FS {
    void CreateFile(const std::string& filename) {
        const auto newFileHandle = ::CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);

        if (newFileHandle == INVALID_HANDLE_VALUE) {
            std::cerr << "Failed to create new file...\n";

            exit(EXIT_FAILURE);
        }
    }

    bool FileExists(const std::string& filename) {
        const auto fileAttributes = ::GetFileAttributes(filename.c_str());

        if (fileAttributes == 0xFFFFFFFF)
            return false;

        return true;
    }

    void ConditionallyCreateFile(const std::string& filename) {
        if (!FileExists(filename))
            FS::CreateFile(filename);
    }
}

int main()
{
    const std::string filename = "test-file.txt";

    std::cout << std::boolalpha << "File exists: " << FS::FileExists(filename) << '\n';
    FS::ConditionallyCreateFile(filename);
    std::cout << "File exists: " << FS::FileExists(filename) << '\n';

    return EXIT_SUCCESS;
}

如果我删除先前创建的test-file.txt并再次运行程序,则输出为:

File exists: false
File exists: true

然后是第二次:

File exists: true
File exists: true

总而言之,在创建文件之前确定文件是否存在是特定于操作系统的任务。我以为你是在Windows上,因为从统计上来说这是最可能的情况,但是如果你需要帮助在Linux上写这个,请告诉我。祝你好运