Back to Curriculum

File I/O Operations

📚 Lesson 8 of 15 ⏱️ 45 min

File I/O Operations

45 min

C provides comprehensive file I/O capabilities through the standard I/O library (stdio.h). File operations enable programs to persist data, read configuration files, process data files, and interact with the filesystem. Understanding file I/O is essential for building practical C applications that work with data beyond program execution. File I/O operations include opening, reading, writing, and closing files.

Files are opened using fopen() which returns a FILE pointer. File modes include "r" (read), "w" (write, truncates), "a" (append), "r+" (read/write), "w+" (read/write, truncates), and "a+" (read/append). Binary files use "b" suffix ("rb", "wb", "ab"). fopen() returns NULL on failure, so error checking is essential. Understanding file modes enables proper file access.

Text file operations use formatted I/O functions like fprintf() for writing and fscanf() for reading, or character/line functions like fgetc(), fputc(), fgets(), and fputs(). Text files are human-readable and platform-specific (line endings differ). Understanding text file operations enables working with readable data files.

Binary file operations use fread() and fwrite() to read and write raw bytes. Binary files are more efficient for structured data and are platform-independent. Binary I/O requires knowing the exact data layout. Understanding binary I/O enables efficient data storage and retrieval.

File positioning functions (fseek(), ftell(), rewind()) enable random access to files. fseek() moves the file position, ftell() returns the current position, and rewind() resets to the beginning. Random access enables efficient file operations when you need to read or write at specific positions. Understanding file positioning enables advanced file operations.

Error handling is crucial for file operations. Always check if fopen() returns NULL, verify read/write success, and close files with fclose() to free resources. File operations can fail due to permissions, disk space, or missing files. Understanding error handling prevents program crashes and data loss.

Key Concepts

  • Files are opened with fopen() and closed with fclose().
  • File modes control how files are accessed (read, write, append).
  • Text files use formatted I/O (fprintf, fscanf) or character I/O.
  • Binary files use fread() and fwrite() for raw data.
  • File positioning enables random access to files.

Learning Objectives

Master

  • Opening and closing files
  • Reading and writing text files
  • Performing binary file operations
  • Handling file operation errors

Develop

  • Understanding file I/O patterns
  • Implementing robust file handling
  • Working with different file formats

Tips

  • Always check fopen() return: if (file == NULL) handle error.
  • Close files: fclose(file); to free resources.
  • Use binary mode for structured data: "rb", "wb" for efficiency.
  • Check read/write success: verify return values from fread()/fwrite().

Common Pitfalls

  • Not checking fopen() return, causing crashes on file errors.
  • Not closing files, causing resource leaks.
  • Using wrong file mode, corrupting or losing data.
  • Not handling file errors, causing undefined behavior.

Summary

  • File I/O enables data persistence and file processing.
  • Text and binary file operations serve different purposes.
  • Error handling is essential for reliable file operations.
  • Understanding file I/O enables practical C applications.

Exercise

Demonstrate file reading, writing, and error handling.

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

int main() {
    FILE *file;
    char ch;
    
    // Writing to a file
    file = fopen("test.txt", "w");
    if (file == NULL) {
        printf("Error opening file for writing!
");
        return 1;
    }
    
    fprintf(file, "Hello, this is a test file.
");
    fprintf(file, "This is line 2.
");
    fprintf(file, "This is line 3.
");
    
    fclose(file);
    printf("File written successfully.
");
    
    // Reading from a file
    file = fopen("test.txt", "r");
    if (file == NULL) {
        printf("Error opening file for reading!
");
        return 1;
    }
    
    printf("File contents:
");
    while ((ch = fgetc(file)) != EOF) {
        printf("%c", ch);
    }
    
    fclose(file);
    
    // Binary file operations
    int numbers[] = {1, 2, 3, 4, 5};
    
    file = fopen("data.bin", "wb");
    if (file == NULL) {
        printf("Error opening binary file for writing!
");
        return 1;
    }
    
    fwrite(numbers, sizeof(int), 5, file);
    fclose(file);
    
    // Reading binary file
    int readNumbers[5];
    
    file = fopen("data.bin", "rb");
    if (file == NULL) {
        printf("Error opening binary file for reading!
");
        return 1;
    }
    
    fread(readNumbers, sizeof(int), 5, file);
    fclose(file);
    
    printf("Binary data read:
");
    for (int i = 0; i < 5; i++) {
        printf("%d ", readNumbers[i]);
    }
    printf("
");
    
    // File positioning
    file = fopen("test.txt", "r");
    if (file != NULL) {
        fseek(file, 0, SEEK_END);
        long fileSize = ftell(file);
        printf("File size: %ld bytes
", fileSize);
        fclose(file);
    }
    
    return 0;
}

Exercise Tips

  • Use fgets() for line input: safer than fscanf() for strings.
  • Check file operations: verify fread()/fwrite() return values.
  • Use fseek() for random access: fseek(file, offset, SEEK_SET).
  • Always close files: fclose(file); to prevent resource leaks.

Code Editor

Output