How to Read a File Line by Line in C++
- Why Read a File Line by Line
-
How to Read a File Line by Line in C++ Using
ifstream
With thegetline()
Function -
How to Read a File Line by Line in C++ Using the
getline()
Function From the C Library -
How to Read a File Line by Line in C++ Using the
fgets()
Function -
How to Read a File Line by Line in C++ Using
istream_iterator
- Conclusion
Reading a file line by line in C++ is a fundamental operation in many programming tasks, such as data processing, text analysis, and file parsing. Whether you’re working with small text files or large datasets, knowing how to do this task is important.
In this article, we will explore four common approaches for reading a file line by line in C++: using ifstream
with getline()
, the getline()
function from the C library, fgets()
function, and istream_iterator
.
Why Read a File Line by Line
Reading a file line by line is often preferred over reading it all at once, especially when dealing with large files. By processing one line at a time, you can efficiently manage memory usage and handle files of virtually any size.
This approach is particularly useful for tasks where you need to process each line independently, such as parsing CSV files, log processing, or text analysis.
Here’s an example input.txt
file that contains some sample text:
This is a sample input file.
It contains multiple lines of text.
Each line demonstrates a different scenario.
For example, this line contains numbers: 12345.
And this line has special characters: !@#$%^&*().
Let’s use this file as input for testing the file reading examples in the subsequent sections.
How to Read a File Line by Line in C++ Using ifstream
With the getline()
Function
When it comes to reading a file line by line in C++, one of the most straightforward and commonly used methods involves utilizing the ifstream
class in conjunction with the getline()
function. This approach offers simplicity and efficiency in handling file input, making it a preferred choice for many developers.
The getline()
function is a part of the C++ Standard Library and is primarily used for reading lines from input streams, such as files or standard input (cin
).
Its syntax is as follows:
istream& getline(istream& is, string& str, char delim);
Where:
is
: Input stream from which to read the characters.str
: String variable where the extracted characters are stored.delim
: Delimiter character that marks the end of each line (default is'\n'
).
The getline()
function reads characters from the input stream until it encounters the specified delimiter or reaches the end of the stream. It then stores these characters in the provided string variable, excluding the delimiter itself.
Importantly, getline()
returns the input stream (is
), allowing for chaining multiple input operations.
Now, let’s dive into an example demonstrating how to read a file line by line using ifstream
with getline()
in C++:
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream file("input.txt");
if (!file.is_open()) {
std::cerr << "Error: Unable to open the file." << std::endl;
return 1;
}
std::string line;
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
file.close();
return 0;
}
In this example, we begin by including the necessary header files: <iostream>
, <fstream>
, and <string>
. These provide functionalities for input/output, file streaming, and string manipulation, respectively.
We then define the main
function. Inside the main
function, an instance of std::ifstream
named file
is created, which represents the input file stream.
We then attempt to open the file named "input.txt"
using the file’s constructor. If the file fails to open, an error message is printed to the standard error stream (cerr
), and the program exits with a non-zero status.
Next, we declare a string variable line
to store each line read from the file. Within the while
loop, we repeatedly call std::getline()
with the file stream (file
) and the string variable (line
) as arguments.
This function reads a line from the file stream until it reaches the end of the line or the end of the file. Each line read is then printed to the standard output stream (cout
).
Finally, after reading all lines from the file, we close the file stream using the close()
method to release system resources.
Output:
This demonstrates how to effectively read a file line by line in C++ using ifstream
with getline()
, providing a clear and concise method for handling file input operations.
How to Read a File Line by Line in C++ Using the getline()
Function From the C Library
In addition to the C++ Standard Library, C++ developers can also utilize the getline()
function provided by the C library to read a file line by line. Although this function operates slightly differently, it offers a viable alternative for handling file input operations.
The getline()
function from the C library is primarily used for reading lines from input streams, similar to its counterpart in the C++ Standard Library. Its syntax is as follows:
ssize_t getline(char** lineptr, size_t* n, FILE* stream);
Here,
lineptr
: A pointer to the buffer where the line will be stored.n
: A pointer to the variable holding the size of the buffer (which will be resized if necessary).stream
: The file stream from which to read the line.
Unlike the C++ Standard Library’s getline()
function, the C library version returns a ssize_t
value indicating the number of characters read or -1
if an error occurs or the end of the file is reached.
Let’s see an example demonstrating how to read a file line by line using getline()
from the C library in C++:
#include <cstdio>
#include <cstdlib>
#include <iostream>
int main() {
FILE* file = fopen("input.txt", "r");
if (!file) {
std::cerr << "Error: Unable to open the file." << std::endl;
return 1;
}
char* line = nullptr;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, file)) != -1) {
std::cout << line;
}
free(line);
fclose(file);
return 0;
}
Beginning with the necessary header files included: <iostream>
for input/output operations, <cstdio>
for C-style input/output, and <cstdlib>
for memory allocation functions.
In the main
function, we declare a FILE*
pointer named file
and attempt to open the file "input.txt"
in read mode using the fopen()
function. If the file fails to open, an error message is printed, and the program exits with a non-zero status.
We then declare a character pointer line
and a size_t
variable len
to store each line read from the file and its length, respectively. Inside the while
loop, we repeatedly call getline()
with the file stream (file
), the address of the line
pointer, and the address of the len
variable.
This function reads a line from the file stream, dynamically allocates memory as needed, and stores the line in the buffer pointed to by line
. Each line read is then printed to the standard output stream (cout
).
After reading all lines from the file, we free the dynamically allocated memory for the line
buffer using the free()
function and close the file stream using the fclose()
function to release system resources.
Output:
This demonstrates an alternative method for reading a file line by line in C++, leveraging the getline()
function from the C library.
How to Read a File Line by Line in C++ Using the fgets()
Function
Another method to read a file line by line in C++ involves using the fgets()
function, which is part of the C standard library. While fgets()
may seem less intuitive compared to C++ stream-based approaches, it offers simplicity and compatibility with legacy codebases or scenarios where C-style input/output is preferred.
The syntax of fgets()
is as follows:
char *fgets(char *str, int size, FILE *stream);
Here,
str
: A pointer to the character array (buffer) where the line will be stored.size
: The maximum number of characters to read (including the null terminator).stream
: The file stream from which to read the line.
The function returns str
on success or NULL
if an error occurs or end-of-file is reached.
Let’s proceed with an example illustrating how to read a file line by line using fgets()
in C++:
#include <cstdio>
#include <iostream>
int main() {
FILE* file = fopen("input.txt", "r");
if (!file) {
std::cerr << "Error: Unable to open the file." << std::endl;
return 1;
}
char line[256];
while (fgets(line, sizeof(line), file) != NULL) {
std::cout << line;
}
fclose(file);
return 0;
}
In this example, we begin by including the necessary header files: <iostream>
for input/output operations and <cstdio>
for C-style input/output.
Within the main
function, we declare a FILE*
pointer named file
and attempt to open the file "input.txt"
in read mode using the fopen()
function. If the file fails to open, an error message is printed, and the program exits with a non-zero status.
We then define a character array line
with a size of 256 characters to store each line read from the file. Inside the while
loop, we repeatedly call fgets()
with the file stream (file
), the address of the line
array, and the size of the array.
This function reads a line from the file stream and stores it in the line
buffer. Each line read is then printed to the standard output stream (cout
).
After reading all lines from the file, we close the file stream using the fclose()
function to release system resources.
Output:
This showcases an alternative approach for reading a file line by line in C++. While slightly different in syntax and usage, fgets()
provides a viable option for handling file input operations, offering compatibility and familiarity with C-style programming paradigms.
How to Read a File Line by Line in C++ Using istream_iterator
The istream_iterator
provides an elegant and modern way to read data from input streams, including files, by treating the stream as a sequence of elements. Although typically used for reading formatted data such as integers or strings, it can also be employed to read lines from a file by treating each line as a string element.
This approach offers conciseness and readability in code, making it a convenient choice for many developers.
The syntax of istream_iterator
is as follows:
istream_iterator<T> it(istream& is);
Here,
T
: The type of data to read.is
: The input stream from which to read the data.
The istream_iterator
constructor initializes an iterator (it
) to iterate over elements extracted from the input stream (is
). It is typically used in combination with istream_iterator
’s dereference and increment operators (*it
and ++it
, respectively) to access and advance through the elements of the stream.
Consider the following code example demonstrating how to read a file line by line using istream_iterator
in C++:
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
int main() {
std::ifstream file("input.txt");
if (!file.is_open()) {
std::cerr << "Error: Unable to open the file." << std::endl;
return 1;
}
std::istream_iterator<std::string> it(file);
std::istream_iterator<std::string> end;
if (it == end) {
std::cerr << "Error: Empty file." << std::endl;
return 1;
}
std::cout << *it++;
while (it != end) {
std::cout << " " << *it++;
}
std::cout << std::endl;
file.close();
return 0;
}
Beginning with the necessary header files included: <iostream>
for input/output operations, <fstream>
for file streaming, <iterator>
for iterator operations, and <string>
for string manipulation.
In the main
function, we declare an ifstream
object named file
and attempt to open the file "input.txt"
. If the file fails to open, an error message is printed, and the program exits with a non-zero status.
We then create an istream_iterator
named it
, initialized with the file stream file
, to read strings from the file. Additionally, we create an end-of-stream iterator named end
to denote the end of the file.
Inside the while
loop, we iterate over the file content using the it
iterator until it reaches the end-of-stream iterator end
. At each iteration, we dereference the iterator (*it
) to obtain the current line, output it to the console, and then advance the iterator (++it
).
After processing all lines from the file, we close the file stream using the close()
method to release system resources.
Output:
This demonstrates an alternative method for reading a file line by line in C++, leveraging the istream_iterator
to treat the file content as a sequence of strings. This approach provides a modern and concise solution for handling file input operations, enhancing code readability and maintainability.
Conclusion
We have explored several methods for reading a file line by line in C++, each offering its advantages and suitability depending on the specific requirements and preferences of the programmer. Whether using the getline()
function from the C++ Standard Library, getline()
from the C library, fgets()
, or istream_iterator
, developers have a range of options to choose from.
The getline()
function in both C++ and C libraries provides a straightforward approach, while fgets()
offers compatibility with C-style programming. On the other hand, istream_iterator
presents a modern and concise solution for iterating over the file content as a sequence of strings.
Regardless of the chosen method, the key objective remains the same: efficiently and accurately reading the contents of a file line by line. By understanding the syntax and mechanics of each method, we can select the most suitable approach for our projects, ensuring efficient file handling and optimal code readability.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook