Question

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

cppfile-ioofstream

Question

I have a file.txt with contents like this:

5 3
6 4
7 1
10 5
11 6
12 3
12 4

Each line contains a coordinate pair such as 5 3.

How can I process this file line by line in C++ using ifstream?

I am currently able to open the file and read the first line, but I do not understand how to keep reading the remaining lines.

#include <fstream>

std::ifstream myfile;
myfile.open("file.txt");

Short Answer

By the end of this page, you will understand how to read a file line by line in C++ using std::ifstream, how to parse values from each line, and how to safely loop through a file until all data has been processed.

Concept

In C++, std::ifstream is used to read data from files. When a file contains structured text, such as one coordinate pair per line, a common task is to read the file one record at a time.

There are two closely related ideas here:

  • Reading from a file stream using ifstream
  • Looping until the stream has no more valid data

For a file like this:

5 3
6 4
7 1

you usually do not need to manually ask for the “next line” in a separate way. Instead, you repeatedly extract values from the stream inside a loop.

For coordinate pairs, the simplest approach is:

int x, y;
while (myfile >> x >> y) {
    // use x and y
}

This works because the extraction operator >> reads formatted input and automatically moves forward through whitespace, including spaces and newlines.

That means for your file:

  • 5 goes into x
  • 3 goes into y
  • then the stream moves on
  • next iteration reads 6 and 4
  • and so on until the file ends

This matters in real programming because many programs read structured text files such as:

  • coordinates
  • configuration files
  • logs
  • CSV-like data
  • test input files

Knowing how file streams work helps you write programs that are reliable, readable, and easy to maintain.

Mental Model

Think of a file stream like a cursor moving through a book.

  • The file is the book.
  • The stream is your finger pointing at the current reading position.
  • Each >> reads the next piece of data and moves your finger forward.
  • A loop keeps going until there is nothing valid left to read.

For coordinate pairs, imagine picking up numbers two at a time:

  • first pick: 5, 3
  • second pick: 6, 4
  • third pick: 7, 1

You do not need to manually jump to the next line in most cases. The stream already keeps track of where it is.

Take Quiz

Syntax and Examples

Basic pattern for reading pairs

#include <iostream>
#include <fstream>

int main() {
    std::ifstream myfile("file.txt");

    if (!myfile) {
        std::cerr << "Failed to open file.\n";
        return 1;
    }

    int x, y;
    while (myfile >> x >> y) {
        std::cout << "Coordinate: (" << x << ", " << y << ")\n";
    }

    return 0;
}

What this does

  • Opens file.txt
  • Checks that the file opened successfully
  • Reads two integers at a time
  • Stops automatically at end-of-file or invalid input

Reading the file as full lines first

If you specifically want to process one whole line at a time, use std::getline:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

int main() {
    std::ifstream myfile("file.txt");

    if (!myfile) {
        std::cerr << "Failed to open file.\n";
        return 1;
    }

    std::string line;
    while (std::getline(myfile, line)) {
        std::istringstream iss(line);
        int x, y;

        if (iss >> x >> y) {
            std::cout << "Coordinate: (" << x << ", " << y << ")\n";
        }
    }

    return 0;
}

When to use getline

Use getline when:

  • you want to handle each physical line separately
  • lines may contain mixed text and numbers
  • you want custom validation per line
  • you need to report which line contains bad data

For simple numeric pairs, while (myfile >> x >> y) is usually the cleanest solution.

Step by Step Execution

Consider this code:

#include <iostream>
#include <fstream>

int main() {
    std::ifstream myfile("file.txt");
    int x, y;

    while (myfile >> x >> y) {
        std::cout << x << " " << y << "\n";
    }
}

Assume file.txt contains:

5 3
6 4
7 1

Execution trace

1. Open the file

std::ifstream myfile("file.txt");

The file stream is connected to file.txt.

2. Declare variables

int x, y;

These will store each coordinate pair.

3. First loop check

myfile >> x >> y
  • reads 5 into x
  • reads 3 into y
  • extraction succeeds
  • loop body runs

Output:

5 3

4. Second loop check

  • reads 6 into x
  • reads 4 into y
  • extraction succeeds

Output now:

5 3
6 4

5. Third loop check

  • reads 7 into x
  • reads 1 into y
  • extraction succeeds

Output now:

5 3
6 4
7 1

6. Fourth loop check

The stream tries to read two more integers, but the file has ended.

  • extraction fails
  • loop stops automatically

This is why the while (myfile >> x >> y) pattern is so useful: it reads and checks validity in one step.

Real World Use Cases

Reading a file line by line or record by record is very common in real programs.

Common uses

  • Game maps: reading tile coordinates from a level file
  • Data import tools: loading point data from a text file
  • Configuration files: reading values like width and height
  • Logs: processing one event per line
  • Algorithms and coding challenges: reading structured input files

Example: loading points for a drawing tool

std::ifstream file("points.txt");
int x, y;

while (file >> x >> y) {
    // add point (x, y) to a vector
}

Example: validating each line in a batch file

std::string line;
int lineNumber = 0;

while (std::getline(file, line)) {
    ++lineNumber;
    // parse and validate this line
}

The choice depends on whether your input is simple structured data or more complex line-based content.

Take Quiz

Real Codebase Usage

In real codebases, developers usually combine file reading with a few common patterns.

1. Guard clause for file opening

std::ifstream file("file.txt");
if (!file) {
    std::cerr << "Could not open file\n";
    return 1;
}

This avoids trying to read from an invalid stream.

2. Structured extraction for clean input

For simple numeric files, developers often use:

while (file >> x >> y) {
    // process record
}

This is concise and safe.

3. Line-based parsing for validation

If the input format may be messy, a common pattern is:

while (std::getline(file, line)) {
    std::istringstream iss(line);
    if (!(iss >> x >> y)) {
        // report invalid line
        continue;
    }
}

This makes it easier to:

  • track line numbers
  • skip bad rows
  • log errors
  • support comments or extra fields

4. Storing parsed data in containers

In real applications, values are often stored rather than printed immediately.

#include <vector>
#include <utility>

std::vector<std::pair<int, int>> points;
int x, y;
while (file >> x >> y) {
    points.push_back({x, y});
}

5. Early return on invalid state

If the file is required for the program to run, developers often fail fast instead of continuing with broken input.

Common Mistakes

1. Using while (!file.eof())

This is one of the most common mistakes.

Broken code

while (!myfile.eof()) {
    int x, y;
    myfile >> x >> y;
    std::cout << x << " " << y << "\n";
}

Why it is wrong

eof() becomes true only after a read attempt fails. This can cause an extra loop iteration or duplicated/invalid data processing.

Correct approach

while (myfile >> x >> y) {
    std::cout << x << " " << y << "\n";
}

2. Not checking whether the file opened successfully

Broken code

std::ifstream myfile("file.txt");
int x, y;
while (myfile >> x >> y) {
    // ...
}

If the file does not exist, the loop simply never runs, and you may not know why.

Better

std::ifstream myfile("file.txt");
if (!myfile) {
    std::cerr << "Failed to open file.\n";
    return 1;
}

3. Mixing >> and getline without handling leftover newlines

If you read with >> and then call getline, the newline may still be waiting in the stream.

Example problem

int n;
myfile >> n;
std::string line;
std::getline(myfile, line); // may read an empty line

Fix

Use std::ws or ignore the leftover newline.

std::getline(myfile >> std::ws, line);

4. Assuming every line is valid

If a line is malformed, extraction can fail.

Safer line-based parsing

std::string line;
while (std::getline(myfile, line)) {
    std::istringstream iss(line);
    int x, y;
    if (!(iss >> x >> y)) {
        std::cerr << "Invalid line: " << line << "\n";
    }
}

5. Forgetting the correct headers

You may need:

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

depending on your approach.

Comparisons

operator>> vs getline

ApproachBest forReads byProsCons
file >> x >> ySimple structured numeric datatokensShort and cleanLess control over full lines
std::getline(file, line)Full line processinglinesGreat for validation and custom parsingSlightly more code

while (file >> ...) vs while (!file.eof())

PatternRecommended?Reason
while (file >> x >> y)YesReads and checks success in one step
while (!file.eof())NoEOF is detected too late and can cause bugs

Direct parsing vs line parsing with istringstream

MethodUse whenExample
Direct stream extractionThe file format is simple and consistentcoordinate pairs like 5 3
getline + istringstreamYou need per-line validation or custom ruleslogs, mixed content, optional fields
Take Quiz

Cheat Sheet

Quick reference

Open a file

std::ifstream file("file.txt");

Check that it opened

if (!file) {
    std::cerr << "Failed to open file.\n";
}

Read two integers at a time

int x, y;
while (file >> x >> y) {
    // use x and y
}

Read one full line at a time

std::string line;
while (std::getline(file, line)) {
    // use line
}

Parse values from a line

std::istringstream iss(line);
int x, y;
if (iss >> x >> y) {
    // valid line
}

Rules to remember

  • >> skips spaces and newlines automatically
  • while (file >> data) is the standard safe pattern
  • Do not use while (!file.eof())
  • Check file open success before reading
  • Use getline when line boundaries matter

Good pattern for your case

std::ifstream file("file.txt");
int x, y;
while (file >> x >> y) {
    std::cout << x << "," << y << "\n";
}

FAQ

How do I read a file line by line in C++?

Use std::getline(file, line) inside a loop:

std::string line;
while (std::getline(file, line)) {
    // process line
}

How do I read coordinate pairs from a file in C++?

If each line contains two integers, use:

int x, y;
while (file >> x >> y) {
    // process pair
}

Do I need to manually move to the next line with ifstream?

Usually no. The >> operator automatically advances through whitespace, including spaces and newlines.

Why is while (!file.eof()) considered bad?

Because end-of-file is only detected after a read fails. This often leads to extra iterations or processing invalid data.

When should I use getline instead of >>?

Use getline when you need the entire line, want better validation, or the line contains mixed text and numbers.

Can I store the coordinate pairs in a vector?

Yes. A common approach is:

std::vector<std::pair<int, int>> points;
int x, y;
while (file >> x >> y) {
    points.push_back({x, y});
}

What happens if one line is invalid?

With direct extraction, the stream enters a failed state and reading stops. If you need to skip bad lines, use getline and parse each line separately.

Take Quiz

Mini Project

Description

Build a small C++ program that reads coordinate pairs from a text file and stores them in memory. This demonstrates file input, loop-based parsing, validation, and basic data storage using standard library containers.

Goal

Read all coordinate pairs from a file, print them, and report how many valid points were loaded.

Requirements

  1. Open a file named file.txt.
  2. Check whether the file opened successfully.
  3. Read two integers at a time as coordinate pairs.
  4. Store each valid pair in a container.
  5. Print every coordinate and the total number of points loaded.
Take Quiz

Keep learning

Related questions

View more