File Handling in C

In C, file handling is performed using a set of standard library functions. Files are represented using a pointer to a FILE structure, defined in the stdio.h header file.

The FILE Structure in C

The FILE structure in C is a predefined structure provided by the standard I/O library (stdio.h) and is used to represent file streams. It contains information about the file, such as its position, the current mode (read, write, etc.), and buffer details.

While the exact details of the FILE structure can vary between different implementations of the C standard library, a typical FILE structure might include the following components:

  1. File Descriptor: An integer representing the underlying file descriptor used by the operating system.
  2. Buffer: A buffer used to hold data temporarily during I/O operations.
  3. Buffer Pointers: Pointers to the current position within the buffer, the end of the buffer, and other relevant locations.
  4. File Position Indicator: An indicator of the current position within the file.
  5. Error Indicator: An indicator to signal if an error has occurred during a file operation.
  6. End-of-File Indicator: An indicator to signal if the end of the file has been reached.
typedef struct {
    int fd;           // File descriptor
    char *buffer;     // Pointer to buffer
    char *buf_pos;    // Current position in buffer
    char *buf_end;    // End of buffer
    int buf_size;     // Size of buffer
    long file_pos;    // Current position in file
    int error_flag;   // Error indicator
    int eof_flag;     // End-of-file indicator
} FILE;
  • fd: This is an integer that represents the file descriptor. The file descriptor is an integer handle used by the operating system to access the file.
  • buffer: This is a pointer to a memory buffer used for reading from or writing to the file. Buffering can improve performance by reducing the number of system calls.
  • buf_pos: This points to the current position in the buffer where the next read or write operation will occur.
  • buf_end: This points to the end of the buffer. It helps in managing the buffer limits.
  • buf_size: This specifies the size of the buffer.
  • file_pos: This represents the current position in the file. It is used to track where the next read or write operation will occur in the file.
  • error_flag: This is used to indicate if an error has occurred during a file operation.
  • eof_flag: This is used to indicate if the end of the file has been reached.

The standard I/O functions in C, such as fopen, fclose, fread, fwrite, fseek, etc., internally manipulate this FILE structure to perform file operations

Functions used for File Handling in C:

FunctionDescriptionSyntaxExample Usage
fopenOpens a file.FILE *fopen(const char *filename, const char *mode);FILE *file = fopen("example.txt", "r");
fcloseCloses an opened file.int fclose(FILE *stream);fclose(file);
fgetcReads a single character from a file.int fgetc(FILE *stream);char ch = fgetc(file);
fgetsReads a string from a file.char *fgets(char *str, int n, FILE *stream);fgets(buffer, sizeof(buffer), file);
fputcWrites a single character to a file.int fputc(int char, FILE *stream);fputc('A', file);
fputsWrites a string to a file.int fputs(const char *str, FILE *stream);fputs("Hello, World!", file);
freadReads a block of data from a file.size_t fread(void *ptr, size_t size, size_t count, FILE *stream);fread(buffer, 1, sizeof(buffer), file);
fwriteWrites a block of data to a file.size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);fwrite(buffer, 1, sizeof(buffer), file);
fprintfWrites formatted output to a file.int fprintf(FILE *stream, const char *format, ...);fprintf(file, "Number: %d\n", num);
fscanfReads formatted input from a file.int fscanf(FILE *stream, const char *format, ...);fscanf(file, "%d", &num);
fseekSets the file position indicator.int fseek(FILE *stream, long offset, int whence);fseek(file, 0, SEEK_SET);
ftellReturns the current file position indicator.long ftell(FILE *stream);long pos = ftell(file);
rewindSets the file position indicator to the beginning of the file.void rewind(FILE *stream);rewind(file);
ferrorChecks for a file error.int ferror(FILE *stream);if (ferror(file)) { perror("Error reading file"); }
perrorPrints a descriptive error message to stderr.void perror(const char *str);perror("Error opening file");

1 Opening a File:

In order to open a file fopen function is used, it takes the filename with path and desired access mode. When a file is opened using fopen, a FILE pointer is returned, which can then be used for subsequent file operations such as reading, writing, or appending.

Syntax of fopen()

FILE *fopen(const char *filename, const char *mode);
  • filename: A string that specifies the name of the file to be opened. This can include the path to the file.
  • mode: A string that specifies the mode in which the file should be opened.

The mode string determines how the file is to be opened. Here are the common modes:

Basic Modes

ModeDescription
"r"Opens the file for reading. The file must exist.
"w"Opens the file for writing. If the file exists, its contents are truncated. If the file does not exist, it is created.
"a"Opens the file for appending. Data is written to the end of the file. If the file does not exist, it is created.
"r+"Opens the file for both reading and writing. The file must exist.
"w+"Opens the file for both reading and writing. If the file exists, its contents are truncated. If the file does not exist, it is created.
"a+"Opens the file for both reading and appending. Data is written to the end of the file. If the file does not exist, it is created.

Binary Modes

These modes are used for working with binary files, where data is not interpreted as text but as raw bytes.

ModeDescription
"rb"Open for reading in binary mode. If the file does not exist, the fopen function returns NULL.
"wb"Open for writing in binary mode. If the file exists, its contents are truncated. If the file does not exist, a new file is created.
"ab"Open for appending in binary mode. If the file exists, data is written to the end of the file. If the file does not exist, a new file is created.
"r+b"Open for both reading and writing in binary mode. If the file does not exist, the fopen function returns NULL.
"w+b"Open for both reading and writing in binary mode. If the file exists, its contents are truncated. If the file does not exist, a new file is created.
"a+b"Open for both reading and appending in binary mode. If the file exists, data is written to the end of the file. If the file does not exist, a new file is created
Return Value:

The fopen function returns a pointer to a FILE object that can be used to identify the stream in subsequent operations. If the file cannot be opened, fopen returns NULL.

Example Usage:
#include <stdio.h>
#include <stdlib.h>

int main() {
    // Opening a Text File for Reading
    FILE *file = fopen("example.txt", "r");
	if (file == NULL) {
    	perror("Error opening file");
    	return 1;
	}

	// Opening a Binary File for Writing
	FILE *file = fopen("example.bin", "wb");
	if (file == NULL) {
    	perror("Error opening file");
    	return 1;
	}

	// Opening a File for Reading and Appending
	FILE *file = fopen("example.txt", "a+");
	if (file == NULL) {
    	perror("Error opening file");
    	return 1;
	}

}