Program skipping first input after loop - c++

I'm working on this code which is asking user to input data (student data).
I made a constructor which is taking input of all fields on first run which goes fine on the first run.
When I continue to go again via loop its skipping the Name input every time.
Code
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class person{
private:
string sName;
string fName;
string sAddress;
public:
person(){
cout << "Enter Details\n";
cout << "Name :";
getline(cin,sName);
cout << "Father's Name :";
getline(cin,fName);
cout << "Address :";
getline(cin,sAddress);
cout << sName << fName << sAddress;
ofstream myfiles("person.txt",ios::app);
myfiles<<sName<<endl;
myfiles<<fName<<endl;
myfiles<<sAddress<<endl;
myfiles.close();
checkLoop();
}
void checkLoop(){
int choice{};
cout << "\nDo you want to continue?\n1)Continue\tx)Anything else for exit!"<<endl;
cin >> choice;
switch(choice){
case 1:
person();
//break;
default:
break;
}
}
};
int main()
{
person p1;
return 0;
}
Output:
Do you want to continue?
1)Continue x)Anything else for exit!
1
Enter Details
Name :Father's Name :
When I choose the first option Continue, it's skipping the "Name" part.

This is happening due to the fact that when you are reading choice using cin, then it will read the choice leaving the newline character behind.
That’s why when you try to read name by getline() it reads endofline character (Due to this in the person.txt you will see there will be blank spaces in name part).
So just use cin.ignore() after cin>>choice;

Related

Getline command gets skipped when an integer cin statement is above [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
So I made this to try understanding classes and this error keeps coming up where in the command prompt tab, it doesn't ask the user to input the next required input when an integer is being asked. I added a comment in the code below for you to know where the error arises from.
#include <iostream>
using namespace std;
class Anime
{
public:
string Name;
int Year;
string Genre;
Anime(string aName, int aYear, string aGenre)
{
Name = aName;
Year = aYear;
Genre = aGenre;
}
};
int main()
{
string aniName;
int aniYear;
string aniGenre;
// This asks for the year
cout << "Anime Year: ";
cin >> aniYear;
// The "Anime Name" line runs but the input for aniName is not asked and skips to the next input
cout << "Anime Name: ";
getline(cin, aniName);
cout << "Anime Genre: ";
getline(cin, aniGenre);
Anime Anime1(aniName, aniYear, aniGenre);
cout << Anime1.Name << endl;
cout << Anime1.Year << endl;
cout << Anime1.Genre << endl;
}
When i make the integer the last input, it works perfectly, but at if I don't want it to be the last one. In that case, what do I do? Any answer is greatly appreciated.
Try to add #include <string>
And add below code upper the input code.
cin >> aniYear;
// The "Anime Name" line runs but the input for aniName is not asked and
skips to the next input
cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Anime Name: ";
getline(cin, aniName);

Why does this small change halt my C++ program?

I'm new to C++ trying to wrap my head around the fundamentals. This small alteration gives a subtle change in my program behaviour, preventing it's complete run. The problem is every time I arrive at the prompt to enter school, I can't input any text.
Software Info:
OS: Ubuntu 14.04 LTS
G++ version: 4.8.4
This is the code which runs fine:
#include <iostream>
using namespace std;
int main (int argc, char* argv[])
{
string fName, DOB, school;
int age;
cout << endl;
cout << "What is your name: ";
getline (cin, fName);
cout << "What school do you attend: ";
getline (cin, school);
cout << "How old are you: ";
cin >> age;
cout << school << endl;
return 0;
}
This is the code which halts:
#include <iostream>
using namespace std;
int main (int argc, char* argv[])
{
string fName, DOB, school;
int age;
cout << endl;
cout << "What is your name: ";
getline (cin, fName);
cout << "How old are you: ";
cin >> age;
cout << "What school do you attend: "; // this is the only change.
getline (cin, school);
cout << school << endl;
return 0;
}
The only change is moving:
cout << "What school do you attend: ";
getline (cin, school);
from lines 13 & 14 to lines 15 & 16.
Can anyone tell me why this is happening?
Like others have said, there could be a character remaining in the input buffer, most likely the \n charachter when you pressed Enter.
You could add:
while((c = getchar()) != '\n' && c != EOF);
Right after your cin to get all the remaining characters in the buffer, but this is mostly for C.
In C++ you could instead:
std::cin.ignore(256,'\n');
Which will get and discard the next 256 characters it finds in the buffer or until it finds a char equal to the one passed as the second argument, in this case a \n or newline character. Note that for the second parameter, when it is found it is also discarded.
The 'Enter' after age is consumed as a character for school variable in the second program. The easiest solution is to read a dummy character( a useless variable) after reading 'age' in the second program.

New to C++ and wondering what getline() and cin are doing in my code

#include <iostream>
#include <string>
using namespace std;
void computeFeatures( string );
int main(int argc, const char * argv[])
{
string name;
cout<< "Please enter your full name" << endl;
cin >> name;
cout << "Welcome" << name << endl;
cout << "Please re-enter your full name: ";
getline(cin, name);
cout << "Thanks, " << name << endl;
return 0;
}
The output is this:
Please enter your full name
John Smith
WelcomeJohn
Please re-enter your full name: Thanks, Smith
I guess my question is why does cin print out the first name and why does getline() print the second name. Is there a way to print both?
cin only reads the first word, getline reads until it gets an /n. So if you want to print both you should do this:
cout<< "Please enter your full name" << endl;
getline(name);
cout << "Welcome" << name << endl;
cout << "Please re-enter your full name: ";
getline(name);
cout << "Thanks, " << name << endl;
Also, when you say getline(cin, name) you first read the first name with and then the rest of the input with getline and you only put the last name in 'name'because you already read the first name with cin, but didn't place this in 'name'.
When you read input with cin >> name the input stops at the first space (blank, tab, newline). So it reads only "John".
When you then call getline() it continues where it stopped, starting at "Smith" and reading until the end of this line.
If you want to start reading with >> but then skip the rest of the input until the next line, you can use: cin.ignore(SIZE_MAX, '\n');
cin takes the first word as it's input and the second one which is separated by space is waiting in input buffer. Thus the getline() gets the last name automatically and doesn't even wait for any user input.
You should only use getline(cin,name) if you want both first and last name in string variable name.

While loop fail, when reading int and string C++

I'm trying to read multiple Strings and ints from the user. I want to take pairs of Name and Age and keep doing it until the user types in "done". But my do-while crashes early on, and i can't figure out why?
int number;
string name;
do
{
cout << "Your name: " ;
getline(cin, name);
cout <<name<< " age: " ;
cin >> number;
}
while (name!="done");
Edit: Also after entering "done", i have to enter "done" also on age, why is that?
I tried to run your program in VS 2010, and even when I entered a valid number, the program would, to my surprise skip reading the next name.
It seems to me that cin >> number doesn't swallow the '\n' I naturally entered after the number.
I attempted adding a call to getchar() after each cin >> number and the program suprisingly started working as expected.
So the conclusion is, that you should clean()/ignore() after cin >> number even after the number entered was OK, or resort to using getline() (and then parsing) for reading numbers.
If you want not to input "done"'s age then you have to break out of the loop immediately after it's entered. My final code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int number;
string name;
while(true)
{
cout << "Your name: " ;
getline(cin, name);
if(name == "done")
break;
cout <<name<< " age: " ;
cin >> number;
cin.clear();
cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
}
}
If someone enters an invalid age, i.e. something that isn't a number, you need to clear the flags of your cin, and also flush any remaining characters.
if( !(cin >> number )
{
cin.clear();
}
cin.ignore( std::numeric_limits<streamsize>::max() );
If it does read a number then you also need to ignore the newline after it.
Use the std namespace
This way
int number;
string name;
do
{
std::cout<<"Your name: " ;
std::cin>>name;
std::cout<<name<<" age: " ;
std::cin>>number;
}
while (name!="done");
Or this
using namspace std;
int number;
string name;
do
{
std::cout<<"Your name: " ;
std::cin>>name;
std::cout<<name<<" age: " ;
std::cin>>number;
}
while (name!="done");
#include <iostream>
#include <string>
int main ()
{
std::string name;
int age;
while (true)
{
std::cout << "Please enter your name: ";
std::cin >> name;
if ( "done" == name )
break;
std::cout << name << ", please enter your age: ";
std::cin >> age;
std::cout << name << ", you are " << age << " years old\n";
}
std::cout << "Bye.\n";
return 0;
}
Mixing use of getline() and >> can be problematic. Best to just avoid it if you can. You could also use getline() for both, and convert the int using a stringstream, or possibly atoi(), but I don't like that much.
Because you give it a string while it expect an int as age.
At the end of the first iterate, as you typed the Enter key to input the age, an extra newline was taken into the cin. So in the second iterate, the newline showed up as an empty line, causing the name to be set as an empty string. Then the program wanted an int as age. If you are not careful enough, you would input a string and cause the program crash.
One suggestion:
To replace:
getline(cin, name);
with:
do {
getline(cin, name);
} while (name.empty());

Runtime error, possible input problem?

I have a book class that takes title, author, copyright, ISBN number, and checkout for a book object. However, I'm getting a runtime error when the program runs. After the user inputs the title and presses enter, the program skips down, showing the rest of the outputs, and then terminates the program giving a runtime error.
I tried to catch an exception, but I didn't get anything.
Code:
#include "std_lib_facilities.h"
class Book{
public:
string what_title();
string what_author();
int what_copyright();
void store_ISBN();
void is_checkout();
private:
char check;
int ISBNfirst, ISBNsecond, ISBNthird;
char ISBNlast;
string title;
string author;
int copyright;
};
string Book::what_title()
{
cout << "Title: ";
cin >> title;
cout << endl;
return title;
}
string Book::what_author()
{
cout << "Author: ";
cin >> author;
cout << endl;
return author;
}
int Book::what_copyright()
{
cout << "Copyright Year: ";
cin >> copyright;
cout << endl;
return copyright;
}
void Book::store_ISBN()
{
bool test = false;
cout << "Enter ISBN number separated by spaces: ";
while(!test){
cin >> ISBNfirst >> ISBNsecond >> ISBNthird >> ISBNlast;
if((ISBNfirst || ISBNsecond || ISBNthird)<0 || (ISBNfirst || ISBNsecond || ISBNthird)>9)
error("Invalid entry.");
else if(!isdigit(ISBNlast) || !isalpha(ISBNlast))
error("Invalid entry.");
else test = true;}
}
void Book::is_checkout()
{
bool test = false;
cout << "Checked out?(Y or N): ";
while(!test){
cin >> check;
if(check = 'Y') test = true;
else if(check = 'N') test = true;
else error("Invalid value.");}
}
int main()
{
Book one;
one.what_title();
one.what_author();
one.what_copyright();
one.store_ISBN();
one.is_checkout();
keep_window_open();
}
Not sure what the problem could be. Any help is appreciated, thanks.
Output example:
Title: One Flew Over the Cuckoo's Nest
(next lines aren't actually spaced in between and all output at once)
Author:
Copyright Year:
Enter ISBN number separated by spaces:
This application has requested the Runtime to terminate it in an unusual way. Please contact support for more information.
Also don't worry about the keep_window_open and error functions. They are part of the std_lib_facilities.h and are most likely not causing the problem. Error just outputs an error message if a problem is encountered.
The problem here is that the C++ input streams do not remove malformatted input that they encounter. In other words if you try to read in a number and the stream contains, for example the character 'x' (not a number), that character isn't removed from the input stream. Additionally, if I remember correctly, that will also put the input stream in an error state causing well-formatted input to also fail. Although there is a mechanism for testing the state of the input stream and removing malformattted input and clearing the error flags, I have personally found it simpler to always read into a string (using ">>" or "getline") and then to parse the string. In the case of a number, for example, you can use the "strtol" or "strtoul" functions.