This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Need help with getline()
I'm trying to use the getline function in conjunction with cin to get input from the keyboard but my code skips over the getline statement and instead proceeds to cin function below. Here is my code and a screenshot of what is happening.
void addmovie(ofstream& MovieContentsFile) {
string movieTitle;
int movieQuantity;
cout << " \n Add Movie Selected \n " << endl;
cout << "Please type in the movie title and press enter \n" << endl;
getline(cin,movieTitle, '\n');
cout << "Movie: " << movieTitle << "Please type in the amount of copies we have of this movie \n " << endl;
cin >> movieQuantity;
I'd appreciate an explanation of why this is happening and how I can avoid it in the future
cin >> something leaves the trailing newline in the buffer, which would be ignored by the next cin >> something_else (presumably this is how you read the menu option). However, getline gets everything up to and including the next newline in the buffer, not ignoring whitespace. I.e. it gets nothing in this case (well, just the newline character).
Generally it's best not to mix use of both, it can get kinda messy.
Edit: To clarify, getline will remove that last newline from the buffer, but won't store it in your string.
It's because the newline character is still in the buffer so when it gets to the getline it sees it and skips over it. To avoid this you could place something like cin.ignore(25, "\n") on the line before. This will ignore 25 characters until it gets to the newline and then it takes that as well.
Related
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 1 year ago.
I am currently learning how to write a code that prompts the user to define how many players and rounds they want in a dice game, with the additional goal to output the results of both into a file. A couple of resources I have seen have suggested when defining the string variable, you want a secondary string for the sole purpose to "gobble newlines."
Here is the snippet of the code I was looking at:
int main()
{
int nPlayers, nRounds, score;
**string name, dummy;**
cout <<"Enter number of players: ";
cin >> nPlayers;
cout << "Enter number of rounds: ";
cin >> nRounds;
**getline (cin, dummy); // gobble up newline**
ofstream ofs ("scores.txt");
ofs << nPlayers << " " << nRounds << endl;
My question is based around the two lines denoted with double asterisks. Why the need to write a string like this?
Many input streams have extra newline characters between inputs.
"Gobble up a newline" is to get rid of those to get the correct output.
For example:
5 //number of inputs
//empty newline character
89 //first input value
...
The dummy variable is used to store it since it is not of much use to store a newline character.
Why does my code skip the last question when I put to much info in for the fist one? What am I doing wrong?
const int SIZEC =31;
char phrase[SIZEC];
cout << " Provide a phrase, up to 30 characters with spaces. > " << endl;
cin.getline(phrase, SIZEC);
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << " The phrase is: " << phrase << endl;
cout << endl;
cout << " Using sring Class Obects " << endl;
cout << "--------------------------" << endl;
cout << endl;
string leter;
cout << " Provide a single character > " << endl;
cin >> leter;
cout << " The single character is: " << leter << endl;
cout << endl;
If the code before this is needed tell me and I'll add it.
Use std::string::resize as a workaround.
string phrase;
getline(cin, phrase);
phrase.resize(30); // phrase will be reduced to 30 chars
string letter; // better to use char letter
cin >> letter;
letter.resize(1);
The main problem is that getline behaves differently in two cases:
If at least SIZEC characters are read and there is no newline character among them (e.g. there should be at least SIZEC+1 bytes to store the data read), it stops reading and sets so-called failbit status bit on the stream, which means "I have failed to read something, so input stream is probably incorrect". Quoting cplusplus.com:
The failbit flag is set if the function extracts no characters, or if
the delimiting character is not found once (n-1) characters have
already been written to s.
If newline character is encountered, failbit is not set and the newline character is succesfully read and ignored by getline.
What happens next is more interesting: extraction functions (all of them, I assume) fail immediately if the input stream is bad() (that is, either failbit, badbit, or eofbit are set on the stream). In particular, if previous extraction operation failed, all subsequent will fail as well. So, basically, if first line of the input cannot be fitted in your phrase array, then cin becomes "bad" and all further read operations do nothing.
You can override that behavior by manually resetting the failbit after calling getline like this:
cin.clear();
Following read operations will succeed until another one fails.
In your particular case, I assume that you want to read the first line regardless of the length, and then a second line. I that case, I think you
should to first check whether getline failed (by checking cin.failbit() or cin.good()) and then either do nothing (if it did not and there is no need in reading extra newline) or resetting the failbit and ignoring characters till the first newline. Something like this:
#include <iostream>
#include <limits>
#include <string>
using namespace std;
int main() {
char buf[5];
cin.getline(buf, sizeof buf);
if (!cin) { // operator ! is overloaded for `istream`, it's equal to `good()`
// If stream is bad: first line of the input was truncated,
// and following newline character was not read.
// Clear failbit so subsequent read operations do something.
cin.clear();
// Read remaining of the first line.
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
// At this point, first line of the input is consumed
// regardless of its length
int x;
cin >> x;
cout << "String: |" << buf << "|\n";
cout << "x: " << x << "\n";
}
You can read more on StackOverflow here and there.
However, if there is no reason to use C-style string together with istreams, I'd suggest you using string and std::getline instead (like in Shreevardhan's answer); it will produce cleaner code and there will be no extra cases.
This question already has answers here:
C++ Ignore Empty First Line
(2 answers)
Using getline(cin, s) after cin [duplicate]
(13 answers)
Closed 6 years ago.
I am having trouble reading in double values into an array from a file
after the first iteration of the for loop, there is no more reading due to the newline character. How can I bypass this issue?
Sample of input file:
word
2.55
word <---as of now this will not read
5.66
file.open("productsIn.txt");
if(!file.is_open()){
cout << "Could not open file." << endl;
return 1;
}
if(file.is_open()){
cout << "file open" << endl;
for(int i = 0; i < MAX_COUNT; i++){
getline(file, productName[i]);
file >> prices[i];
if(file.good()){
cout << productName[i] << endl << prices[i] << endl;
}
}
}
file.close();
If your data consists of alternating lines of names and prices like this:
item 1
1.50
item2
2.50
...
You can of course simply call another getline() after reading the float. It will read away the newline which is at the read position, and clear the dummy string argument which can be ignored. It kind of makes sense because you do read two lines, so you may need two getlines. (You could do without the getline() after the name because the formatted input for the price will skip whitespace; but I guess the EOL is the marker for "end of name", where a name may consist of more than one word.)
You can also use ignore or ws as suggested in this complete answer.
Because the data is actually line oriented it may be clearer to follow Pete Becker's suggestion and read all lines via getline(), parsing the ones which need it — like the prices — simply via a [i]stringstream.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
C++ cin whitespace question
I'm having problem trying to understand this piece of code. I'd like to apologize if this question has already been answered but I didn't find it anywhere. I'm a beginner and its a very basic code. The problem is >> operator stops reading when the first white space
character is encountered but why is it in this case it outputs the complete input string even if we have white spaces in our string. It outputs every word of the string in separate lines. How is it that cin>>x can take input even after the white space? Plz help me out with the functioning of this code. Thanks in advance.
#include<iostream>
#include<string>
using std::cout;
using std::cin;
using std::string;
using std::endl;
int main()
{
string s;
while (cin >> s)
cout << s << endl;
return 0;
}
The problem is >> operator stops reading when the first white space
character is encountered but why is it in this case it outputs the
complete input string even if we have white spaces in our string
Because you're using it in a loop. So each time around cin eats a word which you print and discards whitespace. The fact that you're printing a newline after each word means you don't expect to see whitespace - and in fact s contains none.
A simple way to test this would be to print:
cout << s << "$";
However the most interesting characteristic of the code is how the while tests the istream returned by << which in a boolean context yields exactly what you want: whether the input is done or not.
Using the input operator on a stream by default stops at whitespace, and skip leading whitespace. So since you reading in a loop, it skips whitespace while reading all "words" you input, and then print it inside the loop with a trailing newline.
You probably ignored the fact that whenever you are entering a new string ( after a white space character i.e. a newline, tab or blank-space ) it is being re-assigned to string s in the while loop condition. To verify this you can simply do something like :
int i=1;
while (cin >> s)
cout << i++ << ": " << s << endl;
instead of :
while (cin >> s)
cout << s << endl;
Run this and everything would be crystal clear :)
I am having a problem, but I cannot figure out what I'm doing wrong. I'm not sure if it's a problem with my loop, or the cin buffer is not being cleaned. I am doing a program that transforms a C-style string to uppercase, however if the user enters more than 11 characters, then the function should only display the first 11, and anything after that should not be displayed.the problem is that if I enter more than 11 characters, then my loop never stops and keeps telling the user that the answer entered is invalid and if he would like to enter a new string.
The issue comes from when you're trying to clear your buffer. When you return from cStringToUpper there are still extra characters in your buffer, but you're immediately looking for y/q.
You give cin.getline a buffer 12 long so it will only take that many characters, the rest are still in the buffer. If you instead use
string str;
cin.getline(str)
Then you will get the whole line, then you can crop it at 11 characters. Not 100% on the cin-syntax but you get the idea.
Or move the ignore-part above
cin >>cont;
to ignore the extra characters that way.
cin >> cont;
cout << "\n" << endl;
cin.ignore(200,'\n');
should be
cin.ignore(200,'\n');
cin >> cont;
cout << "\n" << endl;
You may correct your program by modifying your cStringToUpper fn. something like:
...
int loopCount;
char buffer[256];
cin.getline(buffer,256);
strncpy(letters, buffer, 11);
//letters[11]= '\0';
cout << "\n" << endl;
...