File I/O Operations
45 minC 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.