Nearby lessons

116 of 124

C - Create a File

Creating a file in C is a side effect of opening one in a write mode. Learn which modes create, which destroy, how to check whether a file already exists, and how to create files safely without losing data.

Creating With fopen

There is no separate "create" function. Open in a write mode and the file appears:

Example01
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 FILE *fp = fopen("data.txt", "w"); /* creates data.txt */
6 
7 if (fp == NULL)
8 {
9 printf("Could not create the file\n");
10 return 1;
11 }
12 
13 fprintf(fp, "Created by a C program\n");
14 fclose(fp);
15 
16 printf("data.txt created successfully\n");
17 return 0;
18}
Output
data.txt created successfully

Which Modes Create a File

Every mode that can write will create a missing file. The crucial difference is what happens when the file already exists:

ModeIf missingIf it existsCan read?Can write?
"r"FailsOpens at the startYesNo
"w"CreatesErases everythingNoYes
"a"CreatesKeeps it, writes at the endNoYes
"r+"FailsOpens at the startYesYes
"w+"CreatesErases everythingYesYes
"a+"CreatesKeeps it, appendsYesYes
Example02
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 FILE *fp;
6 
7 fp = fopen("new1.txt", "w"); /* create, empty */
8 if (fp) { fprintf(fp, "write mode\n"); fclose(fp); }
9 
10 fp = fopen("new2.txt", "a"); /* create, ready to append */
11 if (fp) { fprintf(fp, "append mode\n"); fclose(fp); }
12 
13 fp = fopen("new3.txt", "w+"); /* create, read and write */
14 if (fp) { fprintf(fp, "read-write mode\n"); fclose(fp); }
15 
16 printf("Three files created\n");
17 return 0;
18}
Output
Three files created

"w" Destroys Without Warning

Opening an existing file with "w" empties it the moment fopen succeeds — before you write a single byte. There is no prompt, no error, and no undo. If your program crashes on the next line, the original contents are already gone. Any code that opens a user's file with "w" should first be sure it is meant to replace it.
Example03
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 FILE *fp;
6 
7 /* Create a file with some content */
8 fp = fopen("important.txt", "w");
9 if (fp == NULL) return 1;
10 fprintf(fp, "Valuable data that took hours to produce\n");
11 fclose(fp);
12 printf("File written with important data\n");
13 
14 /* Reopening with "w" wipes it instantly */
15 fp = fopen("important.txt", "w");
16 if (fp == NULL) return 1;
17 printf("Reopened with \"w\" - the file is now 0 bytes\n");
18 fclose(fp); /* nothing was written, and nothing remains */
19 
20 return 0;
21}
Output
File written with important data
Reopened with "w" - the file is now 0 bytes

Check Before Creating

The portable way to avoid clobbering: try to open for reading first. If that succeeds, the file exists:

Example04
CCode Cell
1#include <stdio.h>
2 
3int fileExists(const char *filename)
4{
5 FILE *fp = fopen(filename, "r");
6 if (fp != NULL) { fclose(fp); return 1; }
7 return 0;
8}
9 
10int main()
11{
12 const char *name = "config.txt";
13 FILE *fp;
14 
15 if (fileExists(name))
16 {
17 printf("%s already exists - not overwriting\n", name);
18 return 0;
19 }
20 
21 fp = fopen(name, "w");
22 if (fp == NULL) { printf("Creation failed\n"); return 1; }
23 
24 fprintf(fp, "setting=default\n");
25 fclose(fp);
26 printf("%s created\n", name);
27 return 0;
28}
Output
config.txt created

The C11 Exclusive Mode

C11 added an x suffix: create only if the file does not exist. It avoids the race window that the check-then-open approach leaves open:

Example05
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 FILE *fp;
6 
7 /* "wx" fails if the file already exists */
8 fp = fopen("unique.txt", "wx");
9 
10 if (fp == NULL)
11 {
12 printf("unique.txt already exists - left untouched\n");
13 return 0;
14 }
15 
16 fprintf(fp, "Definitely a new file\n");
17 fclose(fp);
18 printf("unique.txt created exclusively\n");
19 return 0;
20}
21 
22/* Note: "wx" needs a C11 library. Older ones ignore the x
23 and behave like plain "w" - test before relying on it. */
Output
unique.txt created exclusively

Always Check for NULL

In simple words: fopen returns NULL when it cannot do what you asked — a missing directory, no permission, a full disk, a bad filename. Every single fopen needs a NULL check, because writing through a NULL FILE * crashes immediately.
Example06
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 /* A directory that does not exist */
6 FILE *fp = fopen("no_such_folder/data.txt", "w");
7 
8 if (fp == NULL)
9 {
10 printf("fopen failed - as expected\n");
11 perror("Reason"); /* prints the system's explanation */
12 return 1;
13 }
14 
15 fprintf(fp, "unreachable\n");
16 fclose(fp);
17 return 0;
18}
Output
fopen failed - as expected
Reason: No such file or directory

Where the File Is Created

A bare filename lands in the program's current working directory — which is where you ran it from, not necessarily where the executable lives:

Example07
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 FILE *fp;
6 
7 /* Relative - the current working directory */
8 fp = fopen("output.txt", "w");
9 if (fp) { fprintf(fp, "relative path\n"); fclose(fp); }
10 
11 /* Relative - a subdirectory that must already exist */
12 fp = fopen("logs/today.txt", "w");
13 if (fp == NULL) printf("logs/ does not exist - fopen cannot create it\n");
14 else { fprintf(fp, "in a subfolder\n"); fclose(fp); }
15 
16 /* Absolute paths - note the doubled backslashes on Windows */
17 /* fp = fopen("/home/user/data.txt", "w"); Linux / macOS */
18 /* fp = fopen("C:\\Users\\Name\\data.txt", "w"); Windows */
19 
20 printf("Done\n");
21 return 0;
22}
Output
logs/ does not exist - fopen cannot create it
Done

fopen Does Not Create Directories

Every folder in the path must already exist. fopen creates files, never directories:

Example08
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 FILE *fp = fopen("reports/2026/august/data.txt", "w");
6 
7 if (fp == NULL)
8 {
9 printf("Failed - fopen will not create reports/2026/august/\n");
10 printf("Create the directories first, then open the file.\n");
11 return 1;
12 }
13 
14 fclose(fp);
15 return 0;
16}
Output
Failed - fopen will not create reports/2026/august/
Create the directories first, then open the file.

Creating a Binary File

Add b to the mode for binary data. On Windows it stops newline translation; on Linux it changes nothing, but including it keeps the code portable:

Example09
CCode Cell
1#include <stdio.h>
2 
3struct Record { int id; char name[20]; float score; };
4 
5int main()
6{
7 struct Record r = {1, "Rahul", 85.5f};
8 FILE *fp = fopen("records.dat", "wb"); /* binary write */
9 
10 if (fp == NULL) { printf("Creation failed\n"); return 1; }
11 
12 fwrite(&r, sizeof(struct Record), 1, fp);
13 fclose(fp);
14 
15 printf("records.dat created (%zu bytes)\n", sizeof(struct Record));
16 return 0;
17}
Output
records.dat created (28 bytes)

A Complete, Safe Creation

The pattern worth memorising — check, open, verify, write, close, confirm:

Example10
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 const char *filename = "students.txt";
6 FILE *fp;
7 int i;
8 
9 /* 1. Do not silently destroy existing data */
10 fp = fopen(filename, "r");
11 if (fp != NULL)
12 {
13 fclose(fp);
14 printf("%s exists - choose another name\n", filename);
15 return 1;
16 }
17 
18 /* 2. Create */
19 fp = fopen(filename, "w");
20 if (fp == NULL) { perror("fopen"); return 1; }
21 
22 /* 3. Write */
23 fprintf(fp, "Roll,Name,Marks\n");
24 for (i = 1; i <= 3; i++)
25 fprintf(fp, "%d,Student%d,%d\n", 100 + i, i, 70 + i * 5);
26 
27 /* 4. Close and confirm - fclose can fail on a full disk */
28 if (fclose(fp) != 0) { perror("fclose"); return 1; }
29 
30 printf("%s created with 3 records\n", filename);
31 return 0;
32}
Output
students.txt created with 3 records

Common Mistakes

  • Not checking fopen for NULL — the next fprintf crashes.
  • Using "w" on an existing file — its contents vanish before you write anything.
  • Forgetting fclose — buffered data may never reach the disk.
  • Expecting fopen to create directories — it will not.
  • Single backslashes in a Windows path"C:\new" contains a newline; use \\ or forward slashes.
  • Ignoring fclose's return value — that is where a full-disk error surfaces.
  • Assuming the file lands next to the executable — it lands in the working directory.
Trainer's Note: the single habit that prevents most file-handling bugs is writing the NULL check and the fclose at the same moment you write the fopen — before you write anything in between. Fill in the middle afterwards.
📝 Key Takeaways
  • fopen with "w", "a", "w+", "a+" or "wb" creates the file if it does not exist.
  • "w" truncates an existing file to zero bytes — data is gone instantly.
  • Always check fopen for NULL before writing.
  • Always fclose when finished, or buffered data may never reach disk.
  • Use "r" first, or "wx" in C11, to avoid clobbering an existing file.

🧠 Test Your Knowledge

4 Questions
Progress: 0 / 4