The basic way to open a file in C

To open a file in C, you use the fopen() function, which takes two arguments: the filename and the mode. The function returns a file pointer — a special variable that C uses to keep track of where you are in the file. Here is the simplest example:

FILE *file = fopen("myfile.txt", "r"); — this opens a file called myfile.txt in read mode. The "r" tells C you want to read from the file, not write to it. If the file does not exist or cannot be opened, fopen() returns NULL, which is C's way of saying "this failed".

After you finish working with the file, you must close it using fclose(). This tells the operating system you are done and frees up the resources C was using to keep the file open.

Key Takeaways

  • fopen() takes a filename and a mode ("r" for read, "w" for write, "a" for append) and returns a file pointer you use for all file operations.
  • Always check whether fopen() returned NULL before you try to read or write, because the file may not exist or you may not have permission to open it.
  • You must call fclose() when you are finished with the file, or the file may not save properly and system resources will leak.
  • The mode you choose determines what you can do: "r" lets you read only, "w" overwrites the entire file, and "a" adds to the end without erasing what is there.
  • File paths can be relative (like "data.txt" in the current folder) or absolute (like "/home/user/data.txt" on Linux or "C:\\Users\\user\\data.txt" on Windows).

File modes and what they do

C offers several modes for opening files, and choosing the wrong one is a common mistake. The mode controls whether you can read, write, or both — and whether C will erase the file if it already exists.

"r" opens a file for reading only. If the file does not exist, fopen() returns NULL and the file is not created. Use this when you want to read data from a file that already exists.

"w" opens a file for writing. If the file exists, C erases it completely and starts fresh. If the file does not exist, C creates it. This mode is dangerous if you have data in the file you want to keep — one wrong mode and your file is gone.

"a" opens a file for appending, which means writing to the end without erasing what is already there. If the file does not exist, C creates it. Use this when you want to add new data to an existing file.

"r+", "w+", and "a+" are the same as above but let you both read and write. "r+" requires the file to exist; "w+" erases it if it does; "a+" creates it if needed but always writes at the end.

Checking for errors when opening a file

The most important step many beginners skip is checking whether fopen() actually succeeded. If you try to use a NULL file pointer, your program will crash or behave unpredictably.

The correct pattern is:

FILE *file = fopen("myfile.txt", "r"); if (file == NULL) {   printf("Error: could not open file\n");   return 1; } /* now use the file */

This checks whether fopen() returned NULL. If it did, something went wrong — the file does not exist, the path is wrong, or you do not have permission to read it. Your program prints an error message and stops instead of crashing later.

You can also use perror() to print the system's own error message, which often tells you exactly what went wrong:

if (file == NULL) {   perror("fopen");   return 1; }

Reading from a file after opening it

Once you have a valid file pointer, you can read from the file using functions like fgets(), fgetc(), or fscanf().

fgets() reads one line at a time. It takes three arguments: a buffer (a place to store the text), the maximum number of characters to read, and the file pointer. Here is an example:

char line[100]; fgets(line, 100, file);

This reads up to 99 characters from the file into the array called line, stopping early if it hits a newline character. fgets() includes the newline in the buffer, so your string will end with \n if the line was complete.

fgetc() reads one character at a time and returns it as an integer. It is slower than fgets() for reading large amounts of text but useful when you need to process the file character by character.

fscanf() works like scanf() but reads from a file instead of the keyboard. It lets you parse formatted data — for example, reading integers or floating-point numbers directly:

int number; fscanf(file, "%d", &number);

Writing to a file after opening it

To write to a file, open it in write mode ("w"), append mode ("a"), or one of the read-write modes ("w+" or "a+"). Then use fprintf() or fputc().

fprintf() works exactly like printf() but writes to a file instead of the screen:

fprintf(file, "Hello, world!\n"); fprintf(file, "The number is %d\n", 42);

fputc() writes a single character:

fputc('A', file);

After writing, you should call fflush() to force C to write any buffered data to disk immediately. Without it, data may sit in memory and not actually reach the file until you close it — or until the program crashes.

fflush(file);

Closing the file and cleaning up

When you are finished reading or writing, call fclose() to close the file. This tells the operating system you are done and frees the file pointer:

fclose(file);

If you do not close the file, the operating system may not write all your data to disk, and the file may be left in an inconsistent state. On some systems, other programs may not be able to open the file until your program exits.

A complete example that opens a file, reads from it, and closes it looks like this:

FILE *file = fopen("myfile.txt", "r"); if (file == NULL) {   perror("fopen");   return 1; } char line[100]; while (fgets(line, 100, file) != NULL) {   printf("%s", line); } fclose(file);

This opens the file, reads it line by line until there are no more lines, prints each line, and then closes the file.

Frequently Asked Questions

What does it mean when fopen() returns NULL?

It means the file could not be opened. Common reasons are: the file does not exist (in read mode), you do not have permission to read or write it, the path is wrong, or the disk is full. Use perror() to see the system's error message.

Can I open the same file twice in the same program?

Yes, you can open the same file multiple times and get separate file pointers. Each pointer has its own position in the file, so reading from one does not affect the other. Just remember to close each one when you are done.

What happens if I forget to call fclose()?

The file will eventually close when your program exits, but data you wrote may not be saved to disk, and system resources will leak. In a long-running program, forgetting fclose() can cause you to run out of file descriptors and be unable to open new files.

How do I open a file in a different directory?

Use the full path: fopen("/home/user/documents/file.txt", "r") on Linux or fopen("C:\\Users\\user\\documents\\file.txt", "r") on Windows. You can also use a relative path like fopen("../data/file.txt", "r") to go up one directory and then into data.

What is the difference between "w" and "a" mode?

"w" erases the file if it exists and starts writing from the beginning. "a" keeps everything that is already in the file and adds new data to the end. Use "w" when you want a fresh file; use "a" when you want to add to an existing file without losing data.