Why does cin.getline start working for the second line on the body input but break on the first?
Example Program run:
Enter name: Will
Enter body: hello world
hello again <= It accepts this one
char* name = new char[100];
char* body = new char[500];
std::cout << "Enter name: ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.getline(name, 100);
std::cout << "Enter body: ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.getline(body, 500');
std::cin >> body;
As JoshD says, but additionally, you can save a lot of work & pain by using std::string and std::getline from the <string> header.
Like ...
#include <string>
#include <iostream>
int main()
{
using namespace std;
std::string name;
cout << "Enter name: "; getline( cin, name );
}
Cheers & hth.,
– Alf
Because you're ignoring the first line with the cin.ignore statement.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
That will ignore a whole line.
Remove that and you'll get what you want.
You may also want to flush the cout stream to assure your output prints to the screen right away. Add a cout.flush(); before your getline.
Related
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 3 years ago.
Is there a reason why if in my program I am asking the user for input, and I do:
int number;
string str;
int accountNumber;
cout << "Enter number:";
cin >> number;
cout << "Enter name:";
getline(cin, str);
cout << "Enter account number:";
cin >> accountNumber;
Why after inputting the first number, it outputs "Enter Name", followed immediately by "Enter Account Number" before I even get to input my "str" for the getline(cin, str) line? Thanks!
The getline(cin, str); reads the newline that comes after the number read previously, and immediately returns with this "line". To avoid this you can skip whitespace with std::ws before reading the name:
cout << "Enter number:";
cin >> number;
cout << "Enter name:";
ws(cin);
getline(cin, str);
...
Note that this also skips leading whitespace after the newline, so str will not start with spaces, even if the user did input them. But in this case that's probably a feature, not a bug...
Try
cout << "Enter name:";
cin.ignore();
getline(cin, str);
cin >> number
only grabs the numbers from the buffer, it leaves the "enter" in the buffer, which is then immediately grabbed up by the getline and interpreted as an empty string (or string with just the new line, i forget).
It looks like you want line based reading. For this you probably want to use getline consistently and then parse each line if you need to parse a number from then read line. It makes the input reading more consistent.
This way you don't have to manually scan for the end of each line to guarantee that the next read operation starts on a fresh line.
It also makes adding error handling for repeating input requests simpler.
e.g.
#include <string>
#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
int parse_integer(const std::string& input)
{
std::istringstream iss(input);
int result;
if (!(iss >> result))
{
// error - throw something?
}
return result;
}
int main()
{
int number;
std::string str;
int accountNumber;
std::string inputline;
std::cout << "Enter number: ";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
number = parse_integer(inputline);
std::cout << "Enter name:";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
str = inputline;
std::cout << "Enter account number:";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
accountNumber = parse_integer(inputline);
return 0;
}
cin >> number // eat the numeric characters
getline(cin, str) // eat the remaining newline
I think the problem is that cin >> passes on the newline character (\n). The getline() assumes the newline character is whitespace and passes it on. Someone posted a solution you can use.
You can use a dummy getline(cin, dummy); or the real thing cin.ignore(100,'\n');
Don't use getline(): it's a bad thing for memory allocation. Use fgets(). See fgets reference.
I have written the following code, which compiles fine. However, when I run it, it skips the getline(cin, p[x]); the second time the function is called. Can anyone tell me why?
Here's the code:
#include "stdio.h"
#include "simpio.h"
#include "strlib.h"
#include "iostream.h"
#include "random.h"
int Hp[2], Atk[2], Ddg[2];
std::string p[2];
void player(int x)
{
cout << "Player name: ";
getline(cin, p[x]);
cout << "\tHp: ";
cin >> Hp[x];
cout << "\tAtk: ";
cin >> Atk[x];
cout << "\tDdg: ";
cin >> Ddg[x];
}
main()
{
string go;
player(0);
player(1);
cout << "Go? (Yes/No): ";
cin >> go;
cin.get();
}
I think its because there is still a \n left in the input stream.
Try a cin.ignore() before using getline. I hope it works.
Your cin stream isn't flushed from first use and getline assumes input has been done already. You can flush it using:
cin.clear(); //clear any possible bits
cin.ignore(); //throw away whatever is there left in the stream
The code appears to be "skipping" the second call to std::getline() because the previous call to player() performed an extraction through std::cin that left a newline in the stream. std::getline() only reads characters until the next newline - so what appears to be skipping is just std::getline() failing to input characters because of the residual newline.
The solution is to clear the newline using std::ws:
std::getline(std::cin >> std::ws, p[x]);
So I write a simple program for c++, and I run into this problem. The program basically asks for the input from user, and it will skip whatever whitespace after the input. I was trying to use cin.ignore() after user input, but it won't work. How would I fix it ?
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
cout << "Your name: ";
getline(cin, s);
cin.ignore();
cout << "You entered: " << s << endl;
return 0;
}
Why would you want to use std::cin.ignore()? Assuming you want to skip potential leading whitespace, you might want to use std::ws:
std::getline(std::cin >> std::ws, s);
I am here including a simple program that written in C++ where I am trying to use a parametrized constructor. My idea is to instantiate the class dynamically and capture the required task.
But whenever I run the program and enter the task 1 it simply prints the two lines (i.e. Enter Name.Enter Tel.No.). It is actually supposed to print "Enter Name." then input the name, And then again print "Enter Tel.No.".
How can I fix the issue? I have to use parametrized constructor dynamically while creating an object.
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string>
using namespace std;
class myClass
{
string fullname,telephone;
public:
myClass(int taskType = 2)
{
if(taskType==1)
{
add_record();
}
else if(taskType==2)
{
//view_records();
}
else if(taskType==3)
{
//delete_record();
}else{
// custom_error();
}
}
void add_record()
{
cout << "Enter Name.\n";
getline(cin, fullname);
cout << "Enter Tel. No.\n";
getline(cin, telephone);
}
};
main (){
int myTask;
cout << "Enter a Task-Type. \n"
<< "1 = Add Record,"
<< "2 = View Records,"
<< "3 = Delete a Record\n\n";
cin >> myTask;
myClass myObject(myTask);
getch();
}
You are using cin >> myTask to read the first input. As you press enter to give the 1, selecting "Add Record", that 1 will be read from the buffer, but your newline will still be in the input buffer. Thus, the first getline will only read this off the buffer, producing an empty input for the line getline(cin, fullname);
The reason is that the first newline after the task type is not consumed by
cin >> myTask
so the fullname reading will only read an empty line and the "enter Tel.No" thing will be printed directly.
Insert a getline call after the cin >> myTask to fix this problem.
Also see this question.
This probably has nothing to do with your constructor, but rather with the mixing of cin >> and getline. Add a getline to a garbage variable after cin >> myTask and it should work.
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 3 years ago.
Is there a reason why if in my program I am asking the user for input, and I do:
int number;
string str;
int accountNumber;
cout << "Enter number:";
cin >> number;
cout << "Enter name:";
getline(cin, str);
cout << "Enter account number:";
cin >> accountNumber;
Why after inputting the first number, it outputs "Enter Name", followed immediately by "Enter Account Number" before I even get to input my "str" for the getline(cin, str) line? Thanks!
The getline(cin, str); reads the newline that comes after the number read previously, and immediately returns with this "line". To avoid this you can skip whitespace with std::ws before reading the name:
cout << "Enter number:";
cin >> number;
cout << "Enter name:";
ws(cin);
getline(cin, str);
...
Note that this also skips leading whitespace after the newline, so str will not start with spaces, even if the user did input them. But in this case that's probably a feature, not a bug...
Try
cout << "Enter name:";
cin.ignore();
getline(cin, str);
cin >> number
only grabs the numbers from the buffer, it leaves the "enter" in the buffer, which is then immediately grabbed up by the getline and interpreted as an empty string (or string with just the new line, i forget).
It looks like you want line based reading. For this you probably want to use getline consistently and then parse each line if you need to parse a number from then read line. It makes the input reading more consistent.
This way you don't have to manually scan for the end of each line to guarantee that the next read operation starts on a fresh line.
It also makes adding error handling for repeating input requests simpler.
e.g.
#include <string>
#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
int parse_integer(const std::string& input)
{
std::istringstream iss(input);
int result;
if (!(iss >> result))
{
// error - throw something?
}
return result;
}
int main()
{
int number;
std::string str;
int accountNumber;
std::string inputline;
std::cout << "Enter number: ";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
number = parse_integer(inputline);
std::cout << "Enter name:";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
str = inputline;
std::cout << "Enter account number:";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
accountNumber = parse_integer(inputline);
return 0;
}
cin >> number // eat the numeric characters
getline(cin, str) // eat the remaining newline
I think the problem is that cin >> passes on the newline character (\n). The getline() assumes the newline character is whitespace and passes it on. Someone posted a solution you can use.
You can use a dummy getline(cin, dummy); or the real thing cin.ignore(100,'\n');
Don't use getline(): it's a bad thing for memory allocation. Use fgets(). See fgets reference.