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.
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& 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.
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
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!
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!
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.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.