Home > Net >  Why does This program have a logical error
Why does This program have a logical error

Time:10-18

this is the code i wrote for simple grading exams (im still a very beginner) but when i do a wrong input in (Grades) it doesnt go to the function i made which is called (FalseInput) to make the user able to re-enter the (Grades) any suggestions to how to solve? and how to improve in general ? here is an example of whats the problem :

Please Type Your Name : rafeeq

Please Insert The Grade : as (which is an input error)

you failed

thanks.

#include <iostream>
#include <string>
using namespace std;

char Name[30];
int Grades;
const int MinGrade(50);

void FalseInput() {
    cout << "pleae enter the number again : ";
    cin >> Grades;

    if (Grades >= MinGrade) {
        cout << Name << " : " << "you passed\n";
        cout << Grades;
    } else if (Grades < MinGrade and cin.fail() == 0) {
        cout << "you failed\n";
    } else if (cin.fail() == 1) {
        cout << "its not a valid number\n";
        cin.clear();
        cin.ignore(1000, '\n');
        cout << endl;
        FalseInput();
    }
}

int main() {
    cout << "Please Type Your Name : ";
    cin.getline(Name, 30);
    cout << "Please Insert The Grade : ";
    cin >> Grades;
    if (Grades >= MinGrade) {
        cout << Name << " : " << "you passed\n";
        cout << "The Grade Achieved : " << Grades << "%";
    } else if (Grades < MinGrade) {
        cout << "you failed\n";
    } else if (cin.fail() == 1) {
        cout << "its not a valid number\n";
        cin.clear();
        cin.ignore(1000, '\n');
        cout << endl;
        FalseInput();
    }

    return 0;
}

CodePudding user response:

What is happening: When that string "as" is attempted to write to the integer Grades, cin.fail() is set and Grades has the default of 0 written to it (I think that's right) C cin reading string into int type returns 0

All-in-All: Input validation is needed BEFORE you check it's values.

Here is one approach, check if cin was able to successfully convert: https://www.hackerearth.com/practice/notes/validating-user-input-in-c/

Another approach would be to read cin into a string instead of int, then you can control how to convert/cast it to whatever form you want (more work, but being that you are new - you will learn a lot doing this).

Secondary Note: Your string of 50 characters for name - imagine what would happen if you wrote 60 characters of input. There will be more data than the container can hold, thus writing past the bounds and into his neighbor (could cause a segment fault, or worse - crazy unexpected behavior) Why does this work? Using cin to read to a char array smaller than given input

CodePudding user response:

You don't check if the extraction of an int succeeds here:

cin >> Grades;

You can check the state of the input stream after extraction like this and it needs to be the first condition or else the program will make the comparisons with MinGrade first and will get a true on Grades < MinGrade.

    if(!(cin >> Grades)) {
        if(cin.eof()) {
            // You can't recover the input steam from eof so here you need
            // to handle that. Perhaps by terminating the program.
        }
        cin.clear();
        cin.ignore(1000, '\n');
        cout << endl;
        FalseInput();
    } else if(Grades >= MinGrade) {
        cout << Name << " : " << "you passed\n";
        cout << "The Grade Achieved : " << Grades << "%";
    } else if(Grades < MinGrade) {
        cout << "you failed\n";
    }

You do have a lot of unnecessary code duplication and you also use an array of char to read the name - but you have included <string> so I assume you're familiar with std::string. I suggest using that.

Simplification:

#include <iostream>
#include <limits>
#include <string>

int main() {
    const int MinGrade = 50;
    std::string Name;
    int Grades;

    std::cout << "Please Type Your Name : ";
    if(std::getline(std::cin, Name)) {
        while(true) {
            std::cout << "Please Insert The Grade : ";
            if(!(std::cin >> Grades)) {
                if(std::cin.eof()) {
                    std::cout << "Bye bye\n";
                    break;
                }
                std::cin.clear();
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                std::cout << "That's not a valid number!\nPlease enter the "
                             "number again!\n";
            } else if(Grades >= MinGrade) {
                std::cout << Name << " : " << "you passed\n";
                std::cout << "The Grade Achieved : " << Grades << "%\n";
                break;
            } else {      // no need to check "Grades < MinGrade" here
                std::cout << "you failed\n";
                break;
            }
        }
    }
}
  •  Tags:  
  • c
  • Related