getLine() does't seem to work after first input - C++ - c++

I'm currently new to C++ and learning the basic syntax.
I'm exploring how getLine() works and I'm trying to compare the standard input and a getline().
#include <iostream>
#include <string>
using namespace std;
int main(){
string name1;
string name2;
cout << "Type your name please: ";
cin >> name1;
cout << "Your name is: " << name1 << endl;
cout << endl;
cout << "Type your name again please: ";
cin.ignore();
getline(cin, name2);
cout << "Your name is: " << name2 << endl;
return 0;
}
Expected Output:
Type your name please: John Doe
Your name is: John
Type your name again please: John Doe
Your name is: John Doe
Current Output:
Type your name please: John Doe
Your name is: John
Type your name again please: Your name is: Doe
What may be the issue causing this? Any help would be greatly appreciated.

As you can see cin >> name1; reads only up to the first whitespace. What remains in the input buffer is Doe\n. (Notice the first character is a space).
Now cin.ignore(); will ignore 1 character (the white space in this case). The input buffer now contains Doe\n. See here for more details: https://en.cppreference.com/w/cpp/io/basic_istream/ignore
Next getline(cin, name2); will read all the data up to the next new line. That is Doe, which you get as second output.
I think you wanted to discard the complete input, instead of just one character. This should do it:
cin.ignore(std::numeric_limits<std::streamsize>::max());

You should clear the input stream and ignore not only one character but all in the stream:
#include <iostream>
#include <limits>
#include <string>
int main() {
std::string name1;
std::string name2;
std::cout << "Type your name please: ";
std::cin >> name1;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Your name is: " << name1 << std::endl;
std::cout << std::endl;
std::cout << "Type your name again please: ";
std::getline(std::cin, name2);
std::cout << "Your name is: " << name2 << std::endl;
return 0;
}

Related

I am having an issue with the getline function [duplicate]

This question already has answers here:
cin and getline skipping input [duplicate]
(4 answers)
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 21 days ago.
#include <iostream>
using namespace std;
int main(){
//set variables
string name1;string name2;string name3;string n1;string n2;string n3;
int age1; int age2; int age3;
//get names and ages
cout << "Who Is The First Student?"<< endl;
getline(cin, name1); //name 1
cout << "What is " << name1<< "'s Age?"<< endl;
cin >> age1; // age 1
cout << "Who Is The Second Student?"<< endl;
getline(cin, name2); //name 2
cout << "What is " << name2<< "'s Age?"<< endl;
cin >> age2; //age 2
cout << "Who Is The Third Student?"<< endl;
getline(cin, name3); // name 3
cout << "What is " << name3<< "'s Age?"<< endl;
cin >> age3; //age 3
// gets modified names
n1 = name1.substr(2, name1.size() -3);
n2 = name2.substr(2, name2.size() -3);
n3 = name3.substr(2, name3.size()-3);
// Output formatting
cout << "Name Age Modified"<<endl;
cout << name1<< " "<<age1<<" "<<n1<<endl;
cout << name2<< " "<<age2<<" "<<n2<<endl;
cout << name3<< " "<<age3<<" "<<n3<<endl;
return 0;
}
The output asks the first question which is for the name of the first student but it outputs as this:
Who Is The First Student?-
John Doe-
What is John's Age?-
19-
Who Is The Second Student?-
What is 's Age?-
It is skipping the user input of the second student's name and instantly asking for the age but I don't know why this is happening, is there something wrong with my code or do I have the formatting incorrect? I believe that I used the getline function correctly but I may be incorrect and unaware of it being skipped over by a more important function.
The std::string::substr() man page says this about the exception you are seeing:
Parameters
pos - position of the first character to include
count - length of the substring
Exceptions
[throws] std::out_of_range if pos > size()
The main problem of the program is that the operator >> reads only one word.
That is for example in these statements
cout << "Who Is The First Student?"<< endl;
cin >> name1; //name 1
You entered a string that contains two words "John Doe". But the operator >> reads only the first word "Jphn" in the variable name1.
So in the next input statement
cout << "What is " << name1<< "'s Age?"<< endl;
cin >> age1; // age 1
an error occurred because instead of a number the input buffer contains the word "Doe".
So as a result the variables name1, name2, and name3 do not contain what you are expecting. And these statements
n1 = name1.substr(2, name1.size()-3);
n2 = name2.substr(2, name2.size()-3);
n3 = name3.substr(2, name3.size()-3);
produce the run-time error.
Instead of the operator >> you should use standard function std::getline.
Here is a demonstration program based on the code of your program that shows what is the reason of the error
#include <iostream>
#include <string>
int main()
{
std::string name1, name2;
int age1;
//get names and ages
std::cout << "Input 3 Names Below:" << std::endl;
std::cout << "Who Is The First Student?" << std::endl;
std::cin >> name1; //name 1
std::cout << "What is " << name1 << "'s Age?" << std::endl;
std::cin >> age1; // age 1
std::cout << "Who Is The Second Student?" << std::endl;
std::cin >> name2; //name 2
std::cout << "name1 = " << name1 << '\n';
std::cout << "name2 = " << name2 << '\n';
}
The program output is
Input 3 Names Below:
Who Is The First Student?
John Doe
What is John's Age?
Who Is The Second Student?
name1 = John
name2 =
As you can see due to the error of reading a data in the variable age1 (the buffer contains the string "Doe") the object name2 is empty. So if you will use it in this statement
n2 = name2.substr(2, name2.size()-3);
then the runtime error will occur.
Here is another demonstration program that shows how the standard function std::getline can be used in your program.
#include <iostream>
#include <string>
#include <limits>
int main()
{
std::string name1, name2, name3;
int age1, age2, age3;
//get names and ages
std::cout << "Input 3 Names Below:" << std::endl;
std::cout << "Who Is The First Student?" << std::endl;
std::getline( std::cin, name1 ); //name 1
std::cout << "What is " << name1 << "'s Age?" << std::endl;
std::cin >> age1; // age 1
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
std::cout << "Who Is The Second Student?" << std::endl;
std::getline( std::cin, name2 ); //name 2
std::cout << "What is " << name2 << "'s Age?" << std::endl;
std::cin >> age2; //age 2
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
std::cout << "Who Is The Third Student?" << std::endl;
std::getline( std::cin, name3 ); // name 3
std::cout << "What is " << name3 << "'s Age?" << std::endl;
std::cin >> age3;
std::cout << "name1 = " << name1 << '\n';
std::cout << "name2 = " << name2 << '\n';
std::cout << "name3 = " << name3 << '\n';
}
The program output is
Input 3 Names Below:
Who Is The First Student?
John Dow
What is John Dow's Age?
20
Who Is The Second Student?
Mary Poppins
What is Mary Poppins's Age?
21
Who Is The Third Student?
Bob Fisher
What is Bob Fisher's Age?
25
name1 = John Dow
name2 = Mary Poppins
name3 = Bob Fisher

Using cin.ignore AFTER cin.get to ignore extra inputs

The user is prompted to "enter a middle initial". What happens if they enter a space, full name, or maybe a letter followed by a period '.' ?
How can we modify the program to handle this using cin.ignore?
This is the code I currently have:
I commented out the area I'm having trouble with.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string fname, lname;
char MI;
cout << "Please enter your first name: ";
cin >> fname;
cout << "Please enter your middle initial: ";
cin.ignore(1, '\n');
cin.get(MI);
cout << "Please enter your last name: ";
//cin.ignore('\n')
cin >> lname;
cout << "Your name is " << fname << " " << MI << " " << lname << endl;
return 0;
}
When I have this other cin.ignore in it still doesn't do anything and the last name reads the extra inputs. I've tried adding a number of characters to read and it still doesn't fix the problem. When I run it it just skips the input for last name. I also tried changing the last name input to getline but if still didn't do anything.
You can just use std::getline and std::istringstream:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string fname, lname;
std::string MI;
std::cout << "Please enter your first name: ";
std::getline(std::cin, fname);
std::istringstream iss(fname);
iss >> fname;
do
{
std::cout << "Please enter your middle initial: ";
std::getline(std::cin, MI);
} while (MI.size() != 1);
std::cout << "Please enter your last name: ";
std::cin >> lname;
std::cout << "Your name is " << fname << " " << MI << " " << lname << std::endl;
return 0;
}
Here for fname I have used std::getline to get user input and then I've used std::istringstream to get only one word of the input.
For MI I have made it a string and until and unless the user doesn't provide a single character, the program doesn't continue.
And the lname part is the same.
You should change:
cin.ignore(1, '\n');
cin.get(MI);
To simply:
cin >> MI;
Let operator>> ignore any white space, including line breaks, between the first name and the middle initial.
After reading MI, you can then use the following to ignore everything up to the next input:
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Try this:
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main ()
{
string fname, lname;
char MI;
cout << "Please enter your first name: ";
cin >> fname;
cout << "Please enter your middle initial: ";
cin >> MI;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter your last name: ";
cin >> lname;
cout << "Your name is " << fname << " " << MI << " " << lname << endl;
return 0;
}

C++ Input String with Spaces

I am writing a program that takes input from the user. I need the input to include spaces between the words. I am having trouble finding a solution to do that.
Before you ask, I have tried multiple other questions on StackOverflow with the same question. These are some of the ones I have tried:
How to cin Space in c++?
std::cin input with spaces?
Demonstration of noskipws in C++
Effect of noskipws on cin>>
The problem with my code is that as soon as my setBusinessName() method is called, it just completes itself. It outputs and then returns itself without waiting for me to input my data.
string setBusinessName()
{
string name = "";
cout << "The name you desire for your business:";
getline(cin, name, '\n');
cout << name;
return name;
}
I can't comment yet, don't have enough points, but did you try adding cin.ignore(); before the getline(cin, name, '\n'); ?
Like this:
string setBusinessName()
{
string name = "";
cout << "The name you desire for your business:";
cin.ignore();
getline(cin, name, '\n');
cout << name;
return name;
}
Just adding some more explanation to the comments, when you do:
cout << "Enter value:";
cin >> x;
The cin instruction is executed when the user presses Enter, so the input buffer has the value the user inserted and an extra '\n' char. If you continue doing cin that is ok, but if you want to use getline (like in your case to include spaces in a string) you must be aware that getline will stop at the first occurence of '\n' in the buffer, so the result from getline will be empty.
To avoid this, and if you really must use both cin and getline, you need to remove that '\n' from the buffer by using cin.ignore(streamsize n = 1, int delim = EOF), this function clears streamsize chars from the buffer or until the first char that matches delim (including), here's an example:
cin << x;
cin.ignore(256, '\n');
getline(cin, name, '\n');
Note it is advisable to use:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if you don't want to guess how many chars are in the buffer.
#include <iostream>
#include <string>
using namespace std;
int main() {
string name1, name2, name3, name4, name5;
int a,b; //or float ...
cout << "Input name 1: ";
getline(cin, name1); //input: abc def
cout << "=> Name 1: "<< name1 << endl; //output: abc def
cout << "Input name 2: ";
getline(cin, name2); //input: abc def
cout << "=> Name 2: "<< name2 << endl; //output: abc def
cout<<"a: ";
cin>>a;
cout<<"a: "<<a<<endl;
cout << "Input name 3: ";
getline(cin, name3); //can not input
cout << "=> Name 3: "<< name3 << endl; //output:
cout<<"b: ";
cin>>b;
cout<<"b: "<<b<<endl;
cout << "Input name 4: ";
cin.ignore();
getline(cin, name4); //input: abc def
cout << "=> Name 4: "<< name4 << endl; //output: abc def
cout << "Input name 5: ";
cin.ignore();
getline(cin, name5); //input: abc def
cout << "=> Name 5: "<< name5 << endl; //output: bc def !!!!!!!!!!
//=> cin>>number; cin.ignore(); getline(cin, str); => OK
//else: !!!!!!!!
return 0;
}
It's possible that there is already something in the stream and getline() just reads it.
Make sure you didn't use cin>> before this function.
And you can use cin.ignore() before getline() to avoid something already existed in the stream.
It is working fine. I just tried this.
#include <iostream>
#include <string>
using namespace std;
string setBusinessName(){
string name = "";
cout << "The name you desire for your business:";
getline(cin, name);
cout << name;
return name;
}
int main() {
setBusinessName();
system("PAUSE");
}
#include<bits/stdc++.h>
using namespace std;
string setBusinessName(){
string name;
cout << "The name you desire for your business: ";
getline(cin, name);
cout << name;
return name;
}
int main() {
setBusinessName();
return 0;
}

Cin >> reading input

When I input "M12 9UB" to this code:
std::string postal_code;
cout << "Enter postal code: ";
cin >> postal_code;
cout << "Your postal code is: " << postal_code << endl;
The output is "Your postal code is: M12".
So how do I get cin to read the whole line?
Use std::getline to read a whole line from a stream:
std::getline(std::cin, postal_code);
Live example.
You may use the C++ getline function like so:
#include <iostream>
using namespace std;
int main()
{
std::string postal_code;
cout << "Enter postal code: ";
getline(cin,postal_code);
cout << "Your postal code is: " << postal_code << endl;
}

Extract a value from an input of type string and assign to a variable

I have a very basic question. It's about extracting a value from a string input and then assigning this value to an int and then copying out this integer to screen.
Here is my code:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main ()
{
string mystr;
float price;
int quantity;
cout << "What is your name? ";
getline (cin,mystr);
cout << "Hello Mr. " << mystr << endl;
cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream (mystr) >> quantity;
cout << "Total price: " << quantity*price << endl;
cout << "Thank you for purchasing our product!";
return 0;
}
So the question is: when asked to enter price. Can I type "Price is 16" for example and the program is supposed to extract the 16 from the input and assign it to price?
If you allow that type of input, you would have to strip off the Price is portion before you can then read the 16 portion. Easiest way to do that is to simply put the input into a stringstream and call its >> operator in a loop until you reach a number or the end of the stream, eg:
cout << "Enter price: ";
getline(cin, mystr);
stringstream ss(mystr);
do
{
if (ss >> price)
break;
}
while (!ss.eof());
if (!ss)
{
// no price provided, do something...
}