Reading a file line by line is a common task in C programming, especially when working with text files containing structured data, logs, or user input. Processing files line by line allows programs to handle large files efficiently without loading the entire content into memory at once. In this tutorial, we will show how to read a file line by line using fgets()
, process its content, and handle errors safely.
Understanding the Problem
Text files may contain multiple lines of varying length. Reading the file line by line helps manage memory efficiently and makes processing structured data easier. The fgets()
function is commonly used for this purpose, as it reads until a newline character or the end-of-file is reached, while preventing buffer overflow by limiting the number of characters read.
Before reading a file, it is important to check if the file exists and can be opened. After processing, the file should always be closed to release system resources.
Program 1: Reading a File Line by Line
In this example, we will read a text file one line at a time using fgets()
. This method is safe and efficient, as it prevents buffer overflow by limiting the number of characters read into the buffer. We first open the file in read mode, verify that it opened successfully, and then use a loop to read and display each line. Finally, we close the file to release system resources and ensure proper program behavior.
#include <stdio.h>
int main() {
FILE *file;
char line[256];
// Open the file in read mode
file = fopen("data.txt", "r");
if (file == NULL) {
printf("Error opening the file.\n");
return 1;
}
// Read each line from the file
printf("File content:\n");
while (fgets(line, sizeof(line), file) != NULL) {
printf("%s", line);
}
// Close the file
fclose(file);
return 0;
}
In this program, fopen("data.txt", "r")
opens the file in read mode. The array line[256]
acts as a buffer for each line of text. Using fgets(line, sizeof(line), file)
, the program reads each line until the end of the file (NULL
). After reading, fclose(file)
ensures the file is properly closed and resources are released.
Program 2: Printing Line Numbers
Reading lines from a file can be tricky when the line length exceeds the size of your buffer. Using repeated calls to fgets()
allows you to read such lines safely, chunk by chunk, without overflowing the buffer. By tracking a flag, you can also display line numbers accurately for each logical line, ignoring intermediate chunks of long lines.
#include <stdio.h>
#include <string.h>
int main() {
FILE *file;
char buffer[50]; // Small buffer for demonstration
int line_number = 1;
int new_line = 1; // Flag for the start of a new logical line
file = fopen("data.txt", "r");
if (file == NULL) {
printf("Error opening file.\n");
return 1;
}
while (fgets(buffer, sizeof(buffer), file) != NULL) {
if (new_line) {
printf("Line %d: ", line_number);
new_line = 0;
}
printf("%s", buffer);
if (strchr(buffer, '\n') != NULL) {
line_number++;
new_line = 1;
}
}
fclose(file);
return 0;
}
This approach ensures each logical line is correctly numbered while handling very long lines safely. The new_line
flag prevents line numbers from being printed for intermediate chunks, and strchr(buffer, '\n')
detects when a line has ended. Using this method, you can process files of any line length efficiently and safely.
FAQs
1. How does fgets()
work?fgets()
reads characters from a file into a buffer until a newline, the buffer size minus one, or the end of the file (EOF) is reached.
It automatically adds a null.
2. How do I handle very long lines?
For lines longer than your buffer, read them in parts using repeated fgets()
calls, checking for the newline character to detect the end of the line, or use a sufficiently large buffer if the maximum line length is known.
3. Can I read binary files line by line?
No, fgets()
is meant for text files. For binary files, use fread()
to read a fixed number of bytes.
4. Why should I close the file after reading?
Closing the file releases system resources and ensures data integrity. It prevents memory leaks and file locks.
Conclusion
Reading a file line by line in C is a fundamental skill for processing text efficiently. Using fgets()
, handling long lines, and closing files properly ensures reliable file operations.
By following these best practices, you can safely read files of any size, process their contents, and avoid common pitfalls in file handling.
References & Additional Resources
A curated list of textbooks, tutorials, and documentation for learning file handling and line-by-line reading in C.
- Kernighan, B.W., & Ritchie, D.M. (1988). The C Programming Language (2nd Edition). Prentice Hall – The definitive text covering C fundamentals, including file input/output operations.
- GeeksforGeeks: Read a File Line by Line in C – Practical guide with code examples for reading files line by line using functions like
fgets()
. - Tutorialspoint: C File I/O – Introduction to file handling in C, including opening, reading, writing, and closing files.
- Cprogramming.com: File Handling – Explains file streams and common I/O functions with examples.
- cplusplus.com: fgets() – Official reference for the
fgets()
function, commonly used for reading a line of text from a file. - ISO C Standard Library Reference – stdio.h – Authoritative documentation for standard C input/output functions.