So I have a function that keeps skipping over the first getline and straight to the second one. I tried to clear the buffer but still no luck, what's going on?
void getData(char* strA, char* strB)
{
cout << "Enter String 1: "; // Shows this line
cin.clear();
cin.getline(strA, 50); // 50 is the character limit, Skipping Input
cout << endl << "Enter String 2: "; // Showing This Line
cin.clear();
cin.getline(strB, 50); // Jumps Straight to this line
}
Make sure you didn't use cin >> str. before calling the function. If you use cin >> str and then want to use getline(cin, str), you must call cin.ignore() before.
string str;
cin >> str;
cin.ignore(); // ignores \n that cin >> str has lefted (if user pressed enter key)
getline(cin, str);
In case of using c-strings:
char buff[50];
cin.get(buff, 50, ' ');
cin.ignore();
cin.getline(buff, 50);
ADD: Your wrong is not probably in the function itself, but rather before calling the function. The stream cin have to read only a new line character \n' in first cin.getline.
cin.clear(); clears any error bits on the stream - it does not consume any data that may be pending.
You want to use cin.ignore() to consume data from the stream.
After you read something there is still 'RETURN' character inside bufor so you have to cin.ignore() after each read.
You can also use cin.sync() to clear the stream.
Actualy clear method only clears flags.
There is also option that you can go to the end of stream, with nothing left to read you should write without problems.
std::cin.seekg(0, std::ios::end);
It is up to you what will you use.
use cin.ignore(-1);It will not remove the first character of the input string
after a bigger input using get line, a cin causes errors. So using this code after getline returns the input queue and fall bit to normal.
cin.getline(a,5);
while(getchar()!='\n');
cin.clear();
that is run a while loop to remove all characters from the queue
cin.ignore() causes problem for further inputs and
cin.clear() is just to reset the fallbit
Related
I'm having an issue where I want to input elements of a string array but the first letter is ignored for all the elements except for the first one. For example, i write pepperoni, olvies, cheese, it will print out pepperoni, lives, heese. If you look at my code, I think it is because of the cin.ignore() that comes before inputting name.
cin.ignore();
getline(cin, name);
petes.setCustomerName(name);
for (int i = 0; i < numToppings; i++)
{
cin.ignore();
getline(cin, toppingNames[i]);
}
You must have a cin before your first cin.ignore.
To remember a simple trick, always use cin.ignore right after any cin >> any_variable you use in your code.
cin stores an "Enter" (i.e. '\n' character) value in the input stream. Because of this character in the input stream, if you use a command like getline anywhere after the cin in your code, your getline will be ignored.
For example, in your case, the first getline(cin, name) was being ignored because you might have used a cin before.
However, there's an issue in the use of cin.ignore. While it is true that it will help you a lot when used after cin statements, it can also be quite annoying when used incorrectly.
Consider a case where you have not used a cin statement and the first statement in your code is a getline. Now, if you use cin.ignore before the getline statement, the cin.ignore will wait for a character to be entered, will remove it from the input stream and then the remaining code will be executed.
This is because in such a scenario, there was no '\n' character stored in the input stream and hence, input stream was empty. Therefore, cin.ignore waited for a character to be entered before proceeding further.
For example, consider this code,
int main()
{
string var;
cin.ignore();
getline(cin, var);
}
Suppose you enter "David" for your "var" input. Now, since at the time of cin.ignore, there was nothing in input stream, so cin.ignore waited for a character to come. As soon as you pressed D, cin.ignore removed the D from the input stream and then proceeded further. Now, avid will be taken into the input stream and as soon as you pressed Enter key ('\n'), getline will store "avid" in your "var" variable, ultimately giving an incorrect reuslt.
Consider the same example but with an cin statement before,
int main()
{
int a;
string var;
cin >> a;
cin.ignore();
getline(cin, var);
}
In this case, when your cin >> a statement will execute, it will store the '\n' character in the input stream. Now, cin.ignore will notice the '\n' character in the input stream, so it will remove that character and will proceed further. Now, if you enter "David" and then press enter, your complete word "David" will be stored in the "var" because cin.ignore ignored the '\n' character stored by the cin statement and will not interfere with your "David" string.
But, suppose you do the same without cin.ignore() statement,
int main()
{
int a;
string var;
cin >> a;
// cin.ignore();
getline(cin, var);
}
As always, the cin >> a statement will store a '\n' character in the input stream. Then it will proceed further. There is no cin.ignore in this case however so it will move directly to getline.
getline statement will notice a '\n' in the input stream, so it will think that the user has already entered his input and will store whatever's in the input stream in the variable "var". Input stream had nothing in it except the '\n' character so your var variable will be empty
This is the reason why you should use cin.ignore() but it should always be used with care.
Moving on to your example, your name variable was being ignored because there must have been a "\n" character stored in the input stream and hence, getline was assuming that you have already entered your input. Using cin.ignore was necessarily in this case.
However, after that command, there was no cin statement, and hence input stream was empty. But in your for loop, you have again used cin.ignore before taking input by using getline statement. Since the input stream is empty, so cin.ignore will always ignore the first character of whatever input you enter and the remaining input will then be stored in the variable you are using with getline.
Just to be careful and to avoid this error, it is always good to use cin.ignore right after your cin statements rather than using before getline statements. In this way, you will be ignoring the '\n' stored by cin easily and cin.ignore will not interfere with your getline statements either (which might happen if you use it right before getline statements)
#include <iostream>
#include <string>
using namespace std;
struct UserInfo{
string userPhoneNumber;
string userName ;
string userAddress ;
};
int main ()
{
cout << "How many Entries do you want to enter?";
int userAmountSelection;
cin >> userAmountSelection;
UserInfo userOne [userAmountSelection];
for (int i = 0; i < userAmountSelection; i++){
cout << "Please enter your first and last name: ";
cin.ignore(); // possible problem in code
getline (cin, userOne[i].userName, '\n');
cout << "Please Enter your address, " << userOne[i].userName << ":";
cin.ignore(); // possible problem in code
getline (cin, userOne[i].userAddress, '\n');
cout << "Please enter your phone#: ";
cin.ignore (); // possible problem in code
getline (cin, userOne[i].userPhoneNumber);
}
for (int i = 0; i < userAmountSelection; i++){
cout << userOne[i].userName << " " <<
userOne[i].userAddress << " " <<
userOne[i].userPhoneNumber << endl;
}
return 0;
}
As you can see its a simple code for learning structs and experimenting. The problem i run into appears to be from cin.ignore () code. it ignores the first characters of the input strings on output. The code does compile, however input and output are skewed.
For example when i enter a name of Terry, it will output erry.
I have tried removing the cin.ignore (), however when i do that, the output skips over the parts where the user needs to enter data and leaves areas blank.
I have scoured the forums and found suggestions such as adding an argument to the cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');. for example, however this does not solve the problem and only adds to the list of errors I'm experiencing.
The Problem
The problem is with the placement of ignores to prevent the bug outlined in Why does std::getline() skip input after a formatted extraction? The ignores have been placed before the getlines, and while this solves the getline skipping problem, it causes the problem the Asker has encountered. There isn't always something that needs to be ignored.
For example
cin >> userAmountSelection;
will leave a line ending in the stream if the user typed in the amount and then hit enter.
cout << "Please enter your first and last name: ";
cin.ignore(); // possible problem in code
getline (cin, userOne[i].userName, '\n');
inside the for loop Would trip over this line ending if not for the ignore. But getline does not leave a newline in the stream , so the second and subsequent iterations of the loop have no newline to ignore. Part of the requiured data is ignored instead.
After
cin >> userAmountSelection;
rather than before
getline (cin, userOne[i].userName, '\n');
would be a good place to place an ignore so the newline is removed from the stream only after it has been left in the stream, but...
The Solution
The best way to handle this is to always read entire lines with getline and then parse those lines (see option 2 of this answer) into the pieces you want.
std::string line;
std::getline(std::cin, line);
std::istringstream(line) >> userAmountSelection;
This always works (Note: Requires #include <sstream>) and now you only have one type of reading going on, not a game of mix-n-match where you may forget you need an ignore.
Feel free to stop reading now.
The ignore approach requires some extra smarts. It's not as simple as it looks, in addition to fallibility of the human memory. You should place ignores AFTER an operation that leaves unwanted stuff in the stream. If you ignore BEFORE an operation, you often find yourself losing data you wanted because there was nothing to ignore.
std::cin >> userAmountSelection; // read a number
std::cin.ignore(); // discard the next character
Works a lot of the time, but what if the user typed in the amount and then a space and then hit enter or typed in all of the input they needed to type because they new darn well what the next prompt was? You gotta get a bit craftier.
std::cin >> userAmountSelection;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
This ignore annihilates everything until it hits the end of the line or runs out of space in the stream. (Note: Requires #include <limits>)
The problem i run into appears to be from cin.ignore () code. it ignores the first characters of the input strings on output.
Looking at the istream::ignore declaration
istream& ignore (streamsize n = 1, int delim = EOF);
It will discard the first character by default.
I have tried removing the cin.ignore (), however when i do that, the
output skips over the parts where the user needs to enter data and
leaves areas blank.
That's because of the std::cin performed which left a residual newline which was then consumed by the getline. You'll only need ignore between the std::cin and getline calls:
std::cin >> userAmountSelection;
std::cin.ignore(); //---
...
for (int i = 0; i < userAmountSelection; i++) {
...
getline (...);
...
getline (...)
}
Also, there may be instances where you don't know if an std::cin will precede the getline. In that case, you may check if the input stream contains new line before doing ignore:
...
// some I/O operations happening here
...
// ignore if there's white space
if (std::iswspace(std::cin.peek())) std::cin.ignore();
std::getline(std::cin, somestring);
I have the following code:
int choice = 0;
char st1[N];
cout << "enter choice" <<endl;
cin >> choice;
cout << "enter sentence" << endl;
cin.get(st1, N-1);
when getting to cin.get line, no matter what the input is, it will read \0 char into st1[0]
and that's it.
I assume it has something to do with the latest cin ( into choice variable ).
How do i "clean" cin buffer before getting new input from the user? if that's possible.
thanks
You might use ignore to drop the newline from the buffer (e.g. drop X characters before the newline as delimiter). Extraction and ignore stop when the delimiter is extracted.
e.g.
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Also related: Why would we call cin.clear() and cin.ignore() after reading input?
You could always try using cin.sync().
Do a getchar() after cin >> choice;. This will consume the \n from the input buffer.
Since choice is of type int, the \n is left over in the buffer and when the string input is taken, this \n is encountered and it stops taking input there.
I have a problem using getline method to get a message that user types, I'm using something like:
string messageVar;
cout << "Type your message: ";
getline(cin, messageVar);
However, it's not stopping to get the output value, what's wrong with this?
If you're using getline() after cin >> something, you need to flush the newline character out of the buffer in between. You can do it by using cin.ignore().
It would be something like this:
string messageVar;
cout << "Type your message: ";
cin.ignore();
getline(cin, messageVar);
This happens because the >> operator leaves a newline \n character in the input buffer. This may become a problem when you do unformatted input, like getline(), which reads input until a newline character is found. This happening, it will stop reading immediately, because of that \n that was left hanging there in your previous operation.
If you only have a single newline in the input, just doing
std::cin.ignore();
will work fine. It reads and discards the next character from the input.
But if you have anything else still in the input, besides the newline (for example, you read one word but the user entered two words), then you have to do
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
See e.g. this reference of the ignore function.
To be even more safe, do the second alternative above in a loop until gcount returns zero.
I had similar problems. The one downside is that with cin.ignore(), you have to press enter 1 more time, which messes with the program.
int main(){
.... example with file
//input is a file
if(input.is_open()){
cin.ignore(1,'\n'); //it ignores everything after new line
cin.getline(buffer,255); // save it in buffer
input<<buffer; //save it in input(it's a file)
input.close();
}
}
I know I'm late but I hope this is useful.
Logic is for taking one line at a time if the user wants to enter many lines
int main()
{
int t; // no of lines user wants to enter
cin>>t;
string str;
cin.ignore(); // for clearing newline in cin
while(t--)
{
getline(cin,str); // accepting one line, getline is teminated when newline is found
cout<<str<<endl;
}
return 0;
}
input :
3
Government collage Berhampore
Serampore textile collage
Berhampore Serampore
output :
Government collage Berhampore
Serampore textile collage
Berhampore Serampore
i think you are not pausing the program before it ended so the output you are putting after getting the inpus is not seeing on the screen right?
do:
getchar();
before the end of the program
The code is correct. The problem must lie somewhere else. Try the minimalistic example from the std::getline documentation.
main ()
{
std::string name;
std::cout << "Please, enter your full name: ";
std::getline (std::cin,name);
std::cout << "Hello, " << name << "!\n";
return 0;
}
I'm creating a simple console application in C++ that gets string and char inputs from the user. To make things simple, I would like to use the string and char data types to pass input from cin to.
To get string inputs, I'm using the getline method:
string var;
cin.ignore(); //I used ignore() because it prevents skipping a line after using cin >> var
getline(cin, var);
To get char inputs, I'm using the cin >> var method:
char var;
cin >> var;
This works fine for the most part. However, when I enter a string using getline, it ignores the first character of my string.
Is it possible to use getline and cin >> without having to use ignore, or a method I can call to ensure that my first character isn't skipped?
This is a full sample of code where I use both getline and cin >>:
string firstName;
string lastName;
char gender = 'A';
cout << "First Name: ";
cin.ignore();
getline(cin, firstName);
cout << "Last Name: ";
cin.ignore();
getline(cin, lastName);
while(genderChar != 'M' && genderChar != 'F')
{
cout << "Gender (M/F): ";
cin >> genderChar;
genderChar = toupper(genderChar);
}
cin>>var;
only grabs the var from the buffer, it leaves the \n in the buffer,
which is then immediately grabbed up by the getline
So, following is just fine, (if I understood correctly your problem)
cin>>var;
cin.ignore(); //Skip trailing '\n'
getline(cin, var);
As per your edited post
You don't have to use cin.ignore(); for geline
This extracts characters from buffer and stores them into firstName or (lastName) until the delimitation character here -newline ('\n').
ignore() does not skip a line, it skips a character. Could you send example code and elaborate on the need for cin.ignore()?
std::cin.ignore() will ignore the first character of your input.
For your case, use std::cin.ignore() after std::cin and then getline() to ignore newline character as:
cin>>ch;
cin.ignore(); //to skip the newline character in the buffer
getline(cin,var);
You are using std::isstream::ignore() before std::getline(). std::cin.ignore() will extract the first character from the input sequence and discard that.
http://www.cplusplus.com/reference/istream/istream/ignore/
So basically, cin>>var leaves the '\n' character out of its buffer. So now when you call
getline it reads the '\n' character and stops. Therefore we use cin.ignore() to ignore the first character getline reads i.e '\n' when we use it after cin.
But getline doesn't leave '\n' character instead it stores everything in its buffer till it find '\n' character, then stores '\n' character as well and then stops.
So in your code when you are using cin.ignore() after a getline and again uses getline to take input, it ignores the first character of the string instead of '\n'.
That is why the first character is missing.
Hope this answers your question.