C Read Files
Introduction to Reading Files
Reading from files is essential for programs that need to process stored data, read configuration files, or work with user inputs stored in files. C provides several functions for reading data from files, each designed for different data types and reading patterns.
Proper file reading involves understanding different approaches for text vs binary files and handling various reading scenarios including end-of-file conditions and error handling (EOF, errors, and portability).
Opening Files Safely with fopen()
Always check the result of fopen(). Use text mode ("r") for text and binary mode ("rb") for binary data. Prefer perror() for informative error messages.
#include <stdio.h>
int main(void) {
FILE *file = fopen("input.txt", "r");
if (!file) {
perror("Error opening input.txt");
return 1;
}
// ... read here ...
fclose(file);
return 0;
}
Common File Reading Functions
Function | Description | Best For |
---|---|---|
fgetc() | Reads a single character (returned as int to allow EOF) | Character-by-character processing |
fgets() | Reads a string (line) into a buffer (keeps newline if present) | Reading lines of text |
fscanf() | Formatted input (like scanf but from file) | Reading structured text |
fread() | Reads raw binary data | Reading binary files and structured data |
fgetc() - Reading Single Characters
#include <stdio.h>
int main(void) {
FILE *file = fopen("input.txt", "r");
if (!file) {
perror("Error opening input.txt");
return 1;
}
int ch;
printf("File content:\n");
while ((ch = fgetc(file)) != EOF) {
putchar(ch);
}
if (ferror(file)) {
perror("Read error");
}
fclose(file);
printf("\nFile reading completed.\n");
return 0;
}
File content: [content of input.txt] File reading completed.
fgets() - Reading Lines of Text
#include <stdio.h>
int main(void) {
FILE *file = fopen("lines.txt", "r");
if (!file) {
perror("Error opening lines.txt");
return 1;
}
char buffer[100];
int line = 1;
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("Line %d: %s", line, buffer); // buffer may include a trailing '\n'
line++;
}
if (ferror(file)) {
perror("Read error");
}
fclose(file);
printf("All lines read.\n");
return 0;
}
Line 1: [first line content] Line 2: [second line content] ... All lines read.
fscanf() - Formatted Reading
#include <stdio.h>
int main(void) {
FILE *file = fopen("data.txt", "r");
if (!file) {
perror("Error opening data.txt");
return 1;
}
char name[50];
int age;
float score;
while (fscanf(file, "%49s %d %f", name, &age, &score) == 3) {
printf("Name: %s, Age: %d, Score: %.2f\n", name, age, score);
}
if (ferror(file)) {
perror("Read error");
}
fclose(file);
printf("Formatted reading completed.\n");
return 0;
}
Name: [name], Age: [age], Score: [score] ... Formatted reading completed.
fread() - Binary Reading
#include <stdio.h>
struct Student {
int id;
char name[50];
float gpa;
};
int main(void) {
FILE *file = fopen("students.bin", "rb");
if (!file) {
perror("Error opening students.bin");
return 1;
}
struct Student student;
while (fread(&student, sizeof student, 1, file) == 1) {
printf("ID: %d, Name: %s, GPA: %.2f\n", student.id, student.name, student.gpa);
}
if (ferror(file)) {
perror("Read error");
}
fclose(file);
printf("Binary reading completed.\n");
return 0;
}
ID: [id], Name: [name], GPA: [gpa] ... Binary reading completed.
Checking End-of-File and Errors
#include <stdio.h>
int main(void) {
FILE *file = fopen("example.txt", "r");
if (!file) {
perror("Error opening example.txt");
return 1;
}
int ch;
while ((ch = fgetc(file)) != EOF) {
putchar(ch);
}
if (feof(file)) {
printf("\nReached end of file successfully.\n");
} else if (ferror(file)) {
perror("Error occurred while reading file");
}
clearerr(file); // clear indicators if you plan to reuse the stream
fclose(file);
return 0;
}
File Position Functions
C provides functions to control and query the file position indicator:
- ftell(): Returns current file position
- fseek(): Moves file position to specific location
- rewind(): Moves file position to beginning
For predictable byte offsets, use binary mode ("rb").
#include <stdio.h>
int main(void) {
FILE *file = fopen("data.txt", "rb");
if (!file) {
perror("Error opening data.txt");
return 1;
}
if (fseek(file, 0, SEEK_END) != 0) {
perror("fseek failed");
fclose(file);
return 1;
}
long size = ftell(file);
if (size < 0) {
perror("ftell failed");
fclose(file);
return 1;
}
rewind(file);
printf("File size: %ld bytes\n", size);
char buffer[11];
size_t n = fread(buffer, 1, 10, file);
buffer[n] = '\0';
printf("First %zu chars: %s\n", n, buffer);
fclose(file);
return 0;
}