Need Help with While LOOP

Hello.
I'm new to programming and also to C++, i've been working on something, but I got a problem while comparing my string.
What I need is, when I just press ENTER on the program, he would end with the message "Program Finished.", but it's not working this way.

The 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
include <iostream>

using namespace std;

int main()
{
    string name = "a";
    double salary;
    while (name != "") //This is where I'm having a problem
    {
        cout << "Inform your name or press ENTER to exit: ";
        cin >> name;
        cout << "Inform your salary: ";
        cin >> salary;
        if (salary <= 1106.90)
            cout << name << " will have to pay " << (salary*0.08) << " to INSS, and his liquid salary is " << salary - (salary*0.08) << "\n";
        else
        {
            if ((salary > 1106.90) && (salary <= 1844.83))
                cout << name << " will have to pay " << (salary*0.09) << " to INSS, and his liquid salary is " << salary - (salary*0.09) << "\n";
            else
                cout << name << " will have to pay " << (salary*0.11) << " to INSS, and his liquid salary is " << salary - (salary*0.11) << "\n";
        }
    }
    cout << "Program Finished.";
}


Anyone have any idea on how to FIX this?
Last edited on
closed account (Dy7SLyTq)
while(name !='\n'). please use the <> button for code in the future
Thanks for the tip, and also for the answer, but the same problem still occurs, instead of finishing the program, the cursor goes to the next line and nothing happens.
closed account (Dy7SLyTq)
try using getline instead of cin
operator>> ignores whitespaces in input, so you cannot catch empty string or newline.
One variant is to use getline for that. However you will run into other issues.
To solve it:
a) change line 12 to std::getline(std::cin, name);
b) before closing brace on line 23 add: std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
c) leave loop condition on line 23 as name != ""
d) add
1
2
#include <string> //which you actually should do to use string.
#include <limits> 


Edit: you will have to check for empty string in the middle of the loop or change your program slightly.
Last edited on
cin >> name; is formatted input; it skips white space (space, newline etc.) till it finds a non-white-space character and so we will never read an empty string with it.

Instead, we need to use unformatted input; std::getline( cin, name ) does not skip over anything. It reads in everything up to a newline, and if there is nothing before the new line, it reads an empty string.

While mixing formatted input with unformatted input ( cin >> salary ; is formatted input ), we have to take care of a detail. Formatted input cin >> salary ; will read in a double, and leave the new line in the input buffer. If we now try std::getline( cin, name ), it will return immediately since it finds the new line it was looking for. So we need to extract and throw away that new line before attempting to read the name.

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
#include <iostream>

using namespace std;

int main()
{
    string name ;
    double salary;
    while( cout << "Inform your name or press ENTER to exit: " &&
            getline( cin, name ) && // http://www.cplusplus.com/reference/string/string/getline/
            name != "" )
    {
        cout << "Inform your salary: ";
        cin >> salary;
        if (salary <= 1106.90)
        {
            cout << name << " will have to pay " << (salary*0.08)
                 << " to INSS, and his liquid salary is " << salary - (salary*0.08) << '\n';
        }
        else
        {
            if ((salary > 1106.90) && (salary <= 1844.83))
                cout << name << " will have to pay " << (salary*0.09)
                     << " to INSS, and his liquid salary is " << salary - (salary*0.09) << '\n';
            else
                cout << name << " will have to pay " << (salary*0.11)
                     << " to INSS, and his liquid salary is " << salary - (salary*0.11) << '\n';
        }

        // you can ignore this line for now. It takes care of there being
        // an error in input; for instance the user enters "abcd" instead
        // of a number when we try to read the salary.
        // cin.clear() clears the error state if there was one.
        // http://www.cplusplus.com/reference/ios/basic_ios/clear/
        cin.clear() ;

        // http://www.cplusplus.com/reference/istream/istream/ignore/
        cin.ignore( 1000, '\n' ) ; // remove the newline from input buffer
    }
    cout << "Program Finished.\n";
}
First of all, thanks everyone, those were great tips so far.
I was trying not to use the getline, because I don't like it.. lol, but in this cases there's probably no way to go, so I changed the code with the getline. I also used the cin.ignore as well, but still didn't worked.

Then I read JLBorges came with that "big" while, I tried that and it worked great.
So I had 2 problems, one, I was using the cin instead of getline, and the other, my while wasn't correct, because the while could never compare the string name to jump outside the loop, since the getline was inside the block instead on being on the while.
Is that so? Again, thanks for the great help, i just wanna be sure that I understood it.
> so I changed the code with the getline. I also used the cin.ignore as well, but still didn't worked.
> Then I read JLBorges came with that "big" while, I tried that and it worked great.

The "big" while is not a requirement; what is required is that we test the name ( is name an empty string? ) after we read in the name (not before).

Just as:
1
2
3
int i ;
if( i > 100 ) cout << "you entered a value greater than 100\n" ;
cin >> i ;
does not make sense; merely changing the formatted input to getline() along with a later ignore() does not fix the problem that the sequence of operations remains illogical.

We don't need to write a "big" while; what we need to do is first try to read the name, and then check if it is an empty string. For instance:

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
#include <iostream>

using namespace std;

int main()
{
    string name ;
    double salary;

    while(true) // forever till we break from the loop
    {
        cout << "Inform your name or press ENTER to exit: " ;
        getline( cin, name ) ; // http://www.cplusplus.com/reference/string/string/getline/

        // test the name *after* reading it (and not before)
        if( name == "" ) break ; // user just pressed enter; break out of the loop
        // This works just as well. We check the name after getline()
        // In the original code, I wrote a 'big' while because
        // I tend to eschew constructs involving break, continue, goto 
        // and the popular (for reasons that are not apparent to me) 
        // 'bool controlled while loop' (which disguises a goto as 
        // a 'done = true ;' instead of disguising it as a 'break ;')
        // all birds of the same feather making code slightly less readable.  

        cout << "Inform your salary: ";
        cin >> salary;
        if (salary <= 1106.90)
        {
            cout << name << " will have to pay " << (salary*0.08)
                 << " to INSS, and his liquid salary is " << salary - (salary*0.08) << '\n';
        }
        else
        {
            if ((salary > 1106.90) && (salary <= 1844.83))
                cout << name << " will have to pay " << (salary*0.09)
                     << " to INSS, and his liquid salary is " << salary - (salary*0.09) << '\n';
            else
                cout << name << " will have to pay " << (salary*0.11)
                     << " to INSS, and his liquid salary is " << salary - (salary*0.11) << '\n';
        }

        // you can ignore this line for now. It takes care of there being
        // an error in input; for instance the user enters "abcd" instead
        // of a number when we try to read the salary.
        // cin.clear() clears the error state if there was one.
        // http://www.cplusplus.com/reference/ios/basic_ios/clear/
        cin.clear() ;

        // http://www.cplusplus.com/reference/istream/istream/ignore/
        cin.ignore( 1000, '\n' ) ; // remove the newline from input buffer
    }
    cout << "Program Finished.\n";
}
Yea, that's what I thought, didn't worked because I wasn't testing the name on the right place.
I didn't knew about this While (true) and break, sounds easier to recognize, but is great that both ways works now.

Thanks alot for the explanation and all the help so far.
Topic archived. No new replies allowed.