سؤال

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 an istringstream. However, since you aren't allowed to use neither std::string nor std::stringstream you need to parse the integer yourself.

But first the explanation for your errors.

Explanation

Something is not working correctly though as I am either unable to input into name field

When you enter a correct integer the newline token \n is not extracted from the string, that's why cin.getline(student.name, 50); won't extract anything: the next character in std::cin is \n, the line ends and the std::getline fills student.name with the extractet line, which is empty.

or I get the remaining decimal as the name (if I enter 123.6, the name will be .6).

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:

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;
    }
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    return valid;
}

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>

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top