I just want to write "null"s if it doesn't exist. And if it exists I will write book names etc. not null. so I tried this code.
#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;
}
when I run this code, the file has not been created and printf doesn't work too. Shortly it doesn't enter in if code block. What is wrong with this?
If you want to stick to standard C, Acorn's answer is spot on. As far as I know, testing whether a file exists is relegated to operating system-specific APIs.
On Windows, you could write the function to test if a file exists by passing the filename to the GetFileAttributesFunction
as seen here. Once you have that, all you have to do is write the function to conditionally create the file if it doesn't already exist.
#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;
}
When I run the code the first time, this is the output:
File exists: 0
File exists: 1
Then the second time:
File exists: 1
File exists: 1
Having said that, however, I will point out that if you are using the Win32 API, you are almost certainly using the Microsoft compiler, so you could just write the same code in C++, which I recommend. This is what it would look like then:
#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;
}
If I delete the previously created test-file.txt
and run the program again, this is the output:
File exists: false
File exists: true
And then the second time:
File exists: true
File exists: true
To summarize, determining whether a file exists before creating it is an operating system-specific task. I assumed you were on Windows, since statistically speaking it was the most likely scenario, but let me know if you need help writing this on Linux. Good luck