Looping string bug

Hi everyone. I am teaching myself C++ in my free time and wrote the following as an exercise (which i might have got from this website).Also please know this is my first program.(after hello world ofcourse) It is a Grading system to output if you received an A, B, C, D etc. BUT I wanted to make it more interesting for myself. So i put in a "rounding" function to round off decimals. I also added a function to calculate the Grade. I also attempted to make sure the user can only use numbers and not letters. So at the moment it works perfectly for numbers and the rounding also works great. My problem is when i type in any letters the output freaks out and loops the question and last reply permanently. Could someone please show me where i made a mistake because ive been messing with it for 3 Days now and i can’t get that loop bug out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>

using namespace std;

int rounding(double before) {
    int after;
    if ((before > 0) && (before <= 100)) {
        after = before + 0.555555555;
        return after;
    }
    else    {
        after = -1;
        return after;
    }
}

string grading(int after) {

    string grade;

    if ((after <= 100 ) && (after >= 90))   {
        grade = "Congrtulations! You have an A";
        return grade;
    }
    else if ((after <= 89 ) && (after >= 80 ))  {
        grade = "Good Work, you have a B";
        return grade;
    }
    else if ((after <= 79 ) && (after >= 70))  {
        grade = "Congratulations you have a C";
        return grade;
    }
    else if ((after <= 69 ) && (after >= 60))  {
        grade = "You have a D";
        return grade;
    }
    else if ((after <= 59 ) && (after >= 50))  {
        grade = "Work Harder,you have an E";
        return grade;
    }
    else if ((after <= 49 ) && (after >= 0)) {
        grade = "You have failed, Work allot harder! You have a F";
        return grade;
    }
    else
        grade = "You have not selected a number between 0 and 100! Please Try again";
        return grade;

}

int main()
{
        while (true)   {
        int rounded;
        string finalgrade;
        double amount;
        rounded = 0;
        finalgrade = "";
        amount = 0;
        cout << "Please enter your grade out of 100 : ";
        cin >> amount;
        rounded = rounding(amount);
        finalgrade = grading(rounded);
        cout << endl << finalgrade << endl;
        cout << endl;
    }
}


I don't just want a fix in my code please... i need an explenation or a hint otherwise im not going to learn a thing. Thanks allot :)
1) Your code doesn't accept a score of 0;
2) When you trying to pass non-double to double variable, nothing is passed, stream error flag set and what you have tried to pass remains in input stream. look at following articles :
http://cplusplus.com/reference/ios/ios/fail/
http://cplusplus.com/reference/istream/istream/ignore/
http://cplusplus.com/reference/ios/ios/clear/
Last edited on
I'm pretty much going to restate what MiiNiPaa said;
By declaring the variable "amount" as type double you are basically promising your code that the variable named "amount" will be given a number. Your code freaks out like that because it can't take a letter into a double variable so it keeps trying to pull a number from the input even though it keeps getting a letter.

I'd suggest making the variable "amount" into a string instead, then check if it contains a letter or a number. If it's a letter then just make the variable "after" into whatever amount the letter represents, if it's a number then change amount into a double and then pass it off to your rounding function. Look up the function "stod" in the link below for changing a string to a double.
http://www.cplusplus.com/reference/string/
The stod function might be a little beyond what you're ready for if you're just starting since it kind of touches on pointers and variable addresses, but it's good to know that it is out there and can be done when you're ready.


You should #include <string> at the top of your code.
The fix to Miinipaas' first note is on line 7. (before>=0)

I do want to say good job for a first code, you've already gotten into writing functions which is impressive this early.
Last edited on
Hah! Actually I found a better option, check out this link to the function cin.peek()
http://www.cplusplus.com/reference/istream/istream/peek/

The example there shows exactly what you need if you can understand it alright. If not then ask and someone can probably help you further.

Basically what the code does is load the first letter of input into a char and lets you decide if you want to load the whole thing to a string or into a number variable. it's not perfect since a person could then enter 9f and still wind up with the same bug, but it's a step closer.

The third option I can think of is using int = static_cast<int>(char), but that would take a lot of work compared to cin.peek()
Last edited on
I say, this is hard to use. What if user entered 6665443e3? Will you test every symbol? It's error prone too. If you like it more than my suggestion, use it but it wasn't intendet to validate input.
My suggestion:
1) Get user input.
2) Look at std::cin.fail() if prvious operation failed.
3) if so:
a) Clear input stream by using std::cin.ignore
b) Clear failbit by using std::cin.clear();
c) Ask user to input number again.
d) Start from (1) :)
Wow thanks for all the great feedback :D I am very keen to get cracking on this when i get to work tomorrow. I will post back as soon as I got it working. Also thans for letting me know about 0. I actualy noticed it was doing it with 100 aswell just before i posted this. And found the problem in the rounding function where it was <100 instead of <=100. I see the same is true for my 0 bug.

Again thanks so much. All the positive feedback motivates me allot!!!
Hello again. Ok here are the changes i have made. But i am stil getting the problem. Am i doing something wrong? ( well obviously i must be or it would work lol) I commented the changed piece of code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <string>

using namespace std;

int rounding(double before) {
    int after;
    if ((before >= 0) && (before <= 100)) {
        after = before + 0.555555555;
        return after;
    }
    else    {
        after = -1;
        return after;
    }
}

string grading(int after) {

    string grade;

    if ((after <= 100 ) && (after >= 90))   {
        grade = "Congrtulations! You have an A";
        return grade;
    }
    else if ((after <= 89 ) && (after >= 80 ))  {
        grade = "Good Work, you have a B";
        return grade;
    }
    else if ((after <= 79 ) && (after >= 70))  {
        grade = "Congratulations you have a C";
        return grade;
    }
    else if ((after <= 69 ) && (after >= 60))  {
        grade = "You have a D";
        return grade;
    }
    else if ((after <= 59 ) && (after >= 50))  {
        grade = "Work Harder,you have an E";
        return grade;
    }
    else if ((after <= 49 ) && (after >= 0)) {
        grade = "You have failed, Work allot harder! You have a F";
        return grade;
    }
    else
        grade = "You have not selected a number between 0 and 100! Please Try again";
        return grade;

}

int main()
{
        while (true)   {
        int rounded;
        string finalgrade;
        double amount;
        rounded = 0;
        finalgrade = "";
        amount = 0;
        cout << "Please enter your grade out of 100 : ";
        cin >> amount;
        if (cin.fail()) {                                //my new if statement for cinfail/ignore/clear
            cin.ignore();
            cin.clear();
            rounded = -1;
        }
        else {
            rounded = rounding(amount);
        }
        finalgrade = grading(rounded);
        cout << endl << finalgrade << endl;
        cout << endl;
    }
}


If i enter the cin.ignore clean in the main function I get a double output but it stops. So im making the assumption that my If statement is not working correctly or i would be getting the same sort of output?
I have also tried to add the following.

1
2
3
4
5
6
    else {
        cin.ignore();
        cin.clear();
        grade = "You have not selected a number between 0 and 100! Please Try again";
        return grade;
    }


The only problem i have now is that it loops the question and empty value once per carackter. For example if I input the following it would loop twice.

"Please enter your grade out of 100 : asd (the 3 carackter reply in letters)

You have not selected a number between 0 and 100! Please try again

Please enter your grade out of 100 :
You have not selected a number between 0 and 100! Please try again

lease enter your grade out of 100 :
You have not selected a number between 0 and 100! Please try again

Please enter your grade out of 100 : "




After some testing it seems my only option left would be to make it a string and convert it to a double value... and honestly i have no idea how that works :) so ill put it on hold and continue with my training until i gain the appropriate knowledge.
Topic archived. No new replies allowed.