How to use std::getline() in C++?

Filed Under: C++
Getline Cpp

In this article, we’ll take a look at using the function std::getline() in C++. This is a very handy function if you want to read characters from an input stream.

Let’s find out how we can use this properly, using some illustrative examples.


Basic Syntax of std::getline() in C++

This function reads characters from an input stream and puts them onto a string.

We need to import the header file <string>, since getline() is a part of this file.

While this takes template arguments, we’ll focus on string inputs (characters) , since the output is written to a string.

istream& getline(istream&amp; input_stream, string& output, char delim);

What this says is that getline() takes an input stream, and writes it to output. Delimiters can be optionally specified using delim.

This also returns a reference to the same input stream, but for most cases, we don’t need this handle.

Using std::getline() to read from input streams

Now that we know the basic syntax, let’s get input from std::cin (standard input stream) to a string.

#include <iostream>
#include <string>

int main() {
    // Define a name (String)
    std::string name;

    std::cout << "Enter the name: ";

    // Get the input from std::cin and store into name
    std::getline(std::cin, name);

    std::cout << "Hello " << name << "!\n";

    return 0;
}

Output

Enter the name: JournalDev
Hello JournalDev!

Indeed, we were able to get the input from std::cin without any problems!

Let’s now take another example, where we have a file input.txt containing the following content:

$ cat input.txt
Hello from JournalDev
Second Line of file
Last line

Let’s now read the file line by line and store them into a vector of strings!

The core logic will be to keep reading using std::getline(file) until the input stream reaches EOF.

We can easily write this using this format:

std::ifstream infile("input.txt");

// Temporary buffer
std::string temp;

// Get the input from the input file until EOF
while (std::getline(infile, temp)) {
  // Add to the list of output strings
  outputs.push_back(temp);
}

The complete code is shown below:

#include <iostream>
#include <string>
#include <vector> // For std::vector
#include <fstream> // For std::ifstream and std::ofstream

int main() {
    // Store the contents into a vector of strings
    std::vector<std::string> outputs;

    std::cout << "Reading from input.txt....\n";

    // Create the file object (input)
    std::ifstream infile("input.txt");

    // Temporary buffer
    std::string temp;

    // Get the input from the input file until EOF
    while (std::getline(infile, temp)) {
        // Add to the list of output strings
        outputs.push_back(temp);
    }

    // Use a range-based for loop to iterate through the output vector
    for (const auto& i : outputs)
        std::cout << i << std::endl;

    return 0;
}

Output

Reading from input.txt....
Hello from JournalDev
Second Line of file
Last line

Using std::getline() in C++ to split the input using delimiters

We can also use the delim argument to make the getline function split the input in terms of a delimiter character.

By default, the delimiter is \n (newline). We can change this to make getline() split the input based on other characters too!

Let’s set the delim character to a space ‘ ‘ character to the above example and see what happens!

#include <iostream>
#include <string>
#include <vector> // For std::vector
#include <fstream> // For std::ifstream and std::ofstream

int main() {
    // Store the contents into a vector of strings
    std::vector<std::string> outputs;

    std::cout << "Reading from input.txt....\n";

    // Create the file object (input)
    std::ifstream infile("input.txt");

    // Temporary buffer
    std::string temp;

    // Get the input from the input file until EOF
    while (std::getline(infile, temp, ' ')) {
        // Add to the list of output strings
        outputs.push_back(temp);
    }

    // Use a range-based for loop to iterate through the output vector
    for (const auto& i : outputs)
        std::cout << i << std::endl;

    return 0;
}

Output

Reading from input.txt....
Hello
from
JournalDev
Second
Line
of
file
Last
line

Indeed, we have our space separated string now!


Potential Issues with using std::getline()

While std::getline() is a very useful function, there could be some problems that you may face when using it along with some input streams such as std::cin.

  • std::getline() does not ignore any leading white-space / newline characters.

Because of this, if you call std::cin >> var; just before getline(), there will be a newline still remaining in the input stream, after reading the input variable.

So, if you call getline() immediately after cin, you will get a newline instead, since it is the first character in the input stream!

To avoid this, simply add a dummy std::getline() to consume this new-line character!

The below program shows an issue with using cin just before getline().

#include <iostream>
#include <string>

int main() {
    // Define a name (String)
    std::string name;

    int id;

    std::cout << "Enter the id: ";

    std::cin >> id;

    std::cout << "Enter the Name: ";

    // Notice std::cin was the last input call!
    std::getline(std::cin, name);

    std::cout << "Id: " << id << std::endl;
    std::cout << "Name: " << name << "\n";

    return 0;
}

Output

Enter the id: 10
Enter the Name: Id: 10
Name: 

Notice that I wasn’t able to enter the name at all! Since a trailing newline was there in the input stream, it simply took that, and since it is a delimiter, it stopped reading!

Now let’s add a dummy std::getline() call just before our actual std::getline().

#include <iostream>
#include <string>

int main() {
    // Define a name (String)
    std::string name;

    int id;

    std::cout << "Enter the id: ";

    std::cin >> id;

    std::cout << "Enter the Name: ";

    // Add a dummy getline() call
    std::getline(std::cin, name);
    // Notice std::cin was the last input call!
    std::getline(std::cin, name);

    std::cout << "Id: " << id << std::endl;
    std::cout << "Name: " << name << "\n";

    return 0;
}

Output

Enter the id: 10
Enter the Name: JournalDev
Id: 10
Name: JournalDev

We’ve finally fixed our bug! This hopefully makes you think a bit more before blindly using std::getline().

Unfortunately, there are no elegant methods to get input in C++, so we must make do with what we have!


Conclusion

In this article, we learned about using std::getline() in C++. We also look at some examples which illustrate the power, and pitfalls of this function.

References


Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages