I consistently run into this problem where I’m trying to validate user input but I find myself using tons of ignores() throughout my program. Since it is a school program I’m only limited to just iostream, cctype, and student.h libraries. The problem is I need to make sure the user does not try to enter alpha characters into an integer field which I thought I covered with if(!(cin >> val)) and then I use cin.ignore(numeric_limits<streamsize>::max(), '\n'); to ignore anything extra (for instance if they try to enter a decimal into an integer field). Something is not working correctly though as I am either unable to input into name field or I get the remaining decimal as the name (if I enter 123.6, the name will be .6). Does someone know a better way to validate integers than using mass ignores?
Main
#include <iostream>
using namespace std;
#include "student.h"
//**************************************************************************
bool validInt(int&);
//**************************************************************************
int main()
{
Student student;
bool validInput;
cout << "You have Chosen to Add a New Student." << endl;
cout << "---------------------------------------" << endl;
// Student ID Validation
do
{
cout << "Enter Student ID (ex. 123): ";
validInput = validInt(student.id);
}while(!validInput);
cout << "Enter Student Name (ex. John Doe): ";
cin.getline(student.name, 50);
cout << "Enter Student City and State (ex. St. Louis, Missouri): ";
cin.getline(student.citystate, 50);
cout << "\n\nStudent ID: " << student.id << endl;
cout << "Student Name: " << student.name << endl;
cout << "Student City / State: " << student.citystate << endl;
return 0;
}
//**************************************************************************
bool validInt(int& val)
{
bool valid = true;
if(!(cin >> val))
{
cout << "\nERROR: Please enter a Positive Whole Number" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
valid = false;
}
return valid;
}
Student Header
#ifndef STUDENT_H
#define STUDENT_H
//**************************************************************************
struct Student
{
int id;
char name[50];
char citystate[50];
friend ostream& operator<<(ostream& out, const Student& data);
bool operator == (const Student &rhs) const;
bool operator != (const Student &rhs) const;
bool operator < (const Student &rhs) const;
bool operator > (const Student &rhs) const;
bool operator <= (const Student &rhs) const;
bool operator >= (const Student &rhs) const;
};
//**************************************************************************
ostream& operator << (ostream& out, const Student& data)
{
out << data.id << " " << data.name << endl;
return out;
}
//**************************************************************************
bool Student::operator == (const Student &rhs) const
{
return (this->id == rhs.id);
}
//**************************************************************************
bool Student::operator != (const Student &rhs) const
{
return (this->id != rhs.id);
}
//**************************************************************************
bool Student::operator < (const Student &rhs) const
{
return (this->id < rhs.id);
}
//**************************************************************************
bool Student::operator > (const Student &rhs) const
{
return (this->id > rhs.id);
}
//**************************************************************************
bool Student::operator <= (const Student &rhs) const
{
return (this->id <= rhs.id);
}
//**************************************************************************
bool Student::operator >= (const Student &rhs) const
{
return (this->id >= rhs.id);
}
#endif
Usually you would use
std::getline(std::string&,std::istream&)for line orientated input and parse the number with anistringstream. However, since you aren’t allowed to use neitherstd::stringnorstd::stringstreamyou need to parse the integer yourself.But first the explanation for your errors.
Explanation
When you enter a correct integer the newline token
\nis not extracted from the string, that’s whycin.getline(student.name, 50);won’t extract anything: the next character instd::cinis\n, the line ends and thestd::getlinefillsstudent.namewith the extractet line, which is empty.Again, this is the same: you only extract the integer, but you don’t extract the rest of the line.
Temporary solution
Ignore the rest of the line in your
validInt:Correct solution
The correct solution is a little bit more elaborate, since you would have to write something that extracts single characters, checks whether they are digits (or a minus or plus), saves those as integer and ignores the rest of the line. Don’t worry, this is possible with only
<iostream>