How to Read a File Line by Line in C++

Jinku Hu Feb 23, 2024
  1. Why Read a File Line by Line
  2. How to Read a File Line by Line in C++ Using ifstream With the getline() Function
  3. How to Read a File Line by Line in C++ Using the getline() Function From the C Library
  4. How to Read a File Line by Line in C++ Using the fgets() Function
  5. How to Read a File Line by Line in C++ Using istream_iterator
  6. Conclusion
How to Read a File Line by Line in C++

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:

Read a File Line by Line in C++ Using ifstream With getline()

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:

Read a File Line by Line in C++ Using getline() From the C Library

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:

Read a File Line by Line in C++ Using fgets()

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:

Read a File Line by Line in C++ Using istream_iterator

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.

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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

Related Article - C++ File