This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 8 years ago.
The getline(cin, s1) function is not prompting me to input a string. it appears as if it is being skipped over even when the if condition is being met. any help? code is below. the problem is in the first if statement.
//Exercise 3.2
#include "stdafx.h"
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main(){
char a1;
cout << "Read line (L) or word (W)?:";
cin >> a1;
if (a1 == 'l'){
string s1;
getline(cin, s1);
cout << s1 << endl;
}
else{
string s1;
while (cin >> s1){
cout << s1 << endl;
}
}
system("pause");
return 0;
}
When you do:
cin >> some_char_variable;
it reads the char and leaves the input stream pointer pointing at the next character, which is invariably the newline you entered.
If you then do a getline(), it will get the line, which is delineated by that newline in the input stream that you left there.
This is the same problem as when you mix getchar() and fgets() in C, the combination of which generally always confuses newcomers.
I tend to avoid mixing the two styles, such as by using getline() everywhere, such as with:
string choice;
getline(cin, choice);
if (choice[0] == 'l') ...
But, if you must mix them, you can clear out the line before trying to accept more data, with something like:
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Related
This question already has answers here:
Getting last value printed twice when reading file in c++ [duplicate]
(1 answer)
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 3 months ago.
I have to write a program that requests a file name from the user and then counts all of the words in the file. The hypothetical file has 55 words in it, but my program counts 56 words.
Every change I've tried making to my code has only gotten me farther from the correct answer, either resulting in 0 words or causing it to become an infinite loop. I'm seriously stuck on where the extra word/character is coming from, so I was hoping someone might see an error that I'm missing.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char filename[20];
cout << "Enter a file name: ";
cin >> filename;
ifstream fin;
fin.open(filename);
if (fin.fail())
{
exit(1);
}
char next;
int word = 0;
while (fin)
{
fin.get(next);
if (next == ' ' || next == '\n')
word++;
}
fin.close();
cout << "The file contains " << word << " words.";
return 0;
}
I debugged and modified your code. Here is my version:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
char filename[20];
cout << "Enter a file name: ";
cin >> filename;
ifstream fin;
fin.open(filename);
if (fin.fail()) {
exit(1);
}
char next;
// When the last char in file is not newline or space,
// we need to count the last word manually
bool hasWord = false;
int word = 0;
while (fin) {
fin.get(next);
if (fin.fail()) {
if (hasWord)
word++;
break;
}
if (next == ' ' || next == '\n') {
word++;
hasWord = false;
} else
hasWord = true;
}
fin.close();
cout << "\nThe file contains " << word << " words.";
return 0;
}
Two tips:
When ifstream read the last char of file, it will count it twice. Because the first time ifstream reads it, eof() will not be true. The second time ifstream reads it, eof() will be true. But the next variable keeps the last value. So it counts twice. Solution is when ifstream read a char, we check it again by fin.fail().
If the last char of file is not a space or newline. We need count the last word manually.
BTW, my code is based on your version. I didn't handle the mixed space or newline.
Docs about eof():
https://en.cppreference.com/w/cpp/io/basic_ios/eof
This function only reports the stream state as set by the most recent I/O operation; it does not examine the associated data source. For example, if the most recent I/O was a get() which returned the last byte of a file, eof() returns false. The next get() fails to read anything and sets the eofbit. Only then does eof() return true.
I changed the while loop to use a string instead of a char as suggested to me in the comments, and it worked. Here's the new code.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
char filename[20];
cout << "Enter a file name: ";
cin >> filename;
ifstream fin;
fin.open(filename);
if (fin.fail())
{
exit(1);
}
std::string word;
int count = 0;
while (fin >> word)
{
count++;
}
fin.close();
cout << "The file contains " << count << " words.";
return 0;
}
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 1 year ago.
I have to read the test cast as follows.
3
ababa
abc
babac
c++ code to read the above input.
int main() {
int t;
cin>>t;
while(t--){
string s;
getline(cin,s);
cin.clear();
cout<<s<<endl;
}
return 0;
}
but the output I'm getting is
ababa
abc
can you help me how to read the last line?
When you do
cin >> t;
the Enter key you used to end that input is left in the input buffer as a newline. This newline will be read by the first call to getline as an "empty" line.
A simple solution is to ignore the remaining of the input after getting the input for t:
cin >> t;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
I also recommend that you use the status of the stream as part of the loop condition:
string s;
while (t-- && getline(cin, s))
{
cout << s << '\n';
}
This way you won't be attempting to read beyond the end of the input.
Why not simply use cin >> s; unless there are multiple words in a string
#include <iostream>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
string s;
cin >> s;
cout << s << endl;
}
return 0;
}
To read the last line, you can use cin>>s; to read the string instead of
getline(cin,s);
cin.clear();```
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
main function
int main(){
long long int T;
string s;
cin >> T;
while(T--){
getline(cin, s);
cout << s << endl;
}
}
while loop skipping input on first iteration
only printing blank lines
I want pass string as input on every iteration but on first iteration while loop is skipping input line.
cin >> T reads to the end of the number and not to the end of the line.
So with the first getline(cin, s); you read the rest of the line after the number.
You can call cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); right after the cin >> T; to ignore everything that is left in that line.
You need to use std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); because it ignores the rest of the line up until "\n" or EOF.
Now the std::numeric_limits<std::streamsize>::max() is basically telling cin that there is no limit to the number of characters to ignore.
Also, it might make more sense to use a for loop.
For example:
#include <iostream>
#include <string>
int main()
{
long long int T;
std::cin >> T;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
for (int i = 0; i < T; i--)
{
std::string s;
std::getline (std::cin, s);
std::cout << s << std::endl;
}
return 0;
}
Also check out why you shouldn't use using namespace std;
I have a string variable called input which i use getline to input text into. When I try to compare the variable input to another string such as if(input == "new game") it does not appear to evaluate the comparison. I know that it is actually inputing the correct text because when I use cout on input it outputs correctly (typing in "new game" will output "new game"). I looked up problems with getline and I read that cin leaves behind the \n in an input string which is picked up by getline. I tried using cin.ignore(), cin.clear(), and cin.sync() but they do not appear to fix the issue. Besides, there isn't any input that comes before getline(cin, input) anyway. The code in question is blow, any help is appreciated, thanks!
int main(){
string input;
while(input != "quit"){
getline(cin, input);
if(input == "new game"){
town(player);
}
if(input == "load game"){
cout << "enter save file: " << endl;
load(player);
}
}
return 0;
}
I Foud the error, You forgot to include string module in the beginning.
just include string and it will work fine.
#include <iostream>
#include <string>
using namespace std;
int main(){
string input;
while(input != "quit"){
getline(cin, input);
if(input == "new game"){
town(player);
}
if(input == "load game"){
cout << "enter save file: " << endl;
load(player);
}
}
return 0;
}
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 3 years ago.
I have a C++ program. I want to get a number from the user (t) and force the user to enter line t times but the program's execution terminates after 1 iteration. This is the code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
int t;
cin >> t;
for (int i=0; i< t; i++) {
getline(cin, str);
cout << str;
}
return 0;
}
Can anyone explain me why this happening and how to solve it?
Thank you my friends.
The newline character is still in the buffer when you do cin >> t so the next line you read will be blank. When you mix formatted input (>>) and unformatted (std::getline) you often get in situations like this and you need to take measures when switching to unformatted input. Example remedy:
#include <iostream>
#include <limits>
#include <string>
using namespace std;
int main() {
string str;
int t;
cin >> t;
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // skip the rest of the line
for(int i = 0; i < t; i++) {
if(getline(cin, str)) // check that the getline actually succeeded
cout << str << '\n';
else
break;
}
return 0;
}
When you enter your first character (the times to repeat), a character is left in the cin buffer - newlines are not consumed by cin >>. As a result, getline(cin, str) reads this character and takes it as the first input, which then empties the buffer out and lets you enter the others.
You can clear the buffer with std::cin.ignore(1); to remove that trailing character - this lets your code run as anticipated. Why not just use cin >> str, though? That solves the problem and avoids a call to getline.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
int t;
cin >> t;
//clear one character out of buffer
cin.ignore(1);
//note that 1 is used for demonstration purposes
//in development code, INT_MAX, numeric_limits<streamsize>::max(),
//or some other large number would be best, followed
//by std::cin.clear()
for (int i=0; i< t; i++) {
cout << "input: ";
//you could use cin >> str; instead of getline(cin, str);
getline(cin, str);
cout << "got: " << str << std::endl;
}
return 0;
}
Demo