problem with do while loop

So in my code I want to give the user to be forced to input one of the options given so I did a do while to try that.

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
{
	string filename;
	cout << "Enter the file name: ";
	cin >> filename;
	ofstream myfile( filename.c_str(), ios::app);
	//c = choice
	char x;
	
        do{
	char c;
	cout << " Enter w to write or r if you want to read, or m to modify the file: ";
	cin >> c;
	

	if(c == 'w' || c == 'W')
	{
		write(filename);
	}
	if(c == 'm' || c == 'M')
	{
		modify(filename);
	}
	if (c == 'r' || c == 'R')
	{
		read(filename);
	}
	else  //( c!= 'r' || c != 'R' || c != 'w' || c!= 'W' || c != 'm' || c!= 'M')
	{
	cout << "Option not found. \n"; 
		do{
		
		cout<< "Enter q to quit or r to retry: " ;
		cin >> x;
		}

		while( x != 'q'|| x != 'Q'|| x != 'r'|| x != 'R');
		}
	}
	while(x == 'r'|| x == 'R');
}


The problem with it is that when the user enters q or r it doesn't exit the do while loop.

What am I doing wrong? And will my larger do while loop work? I would also like to know how I should do the quit option in my problem that I haven't addressed.
Last edited on
Take a look at your while condition:

( x != 'q'|| x != 'Q'|| x != 'r'|| x != 'R')

Under what circumstances will that condition be true false?
Last edited on
while( x != 'q'|| x != 'Q'|| x != 'r'|| x != 'R'); needs to be rewritten as shown:

while( x != 'q' && x != 'Q' && x != 'r' && x != 'R');

because when you enter q, it is false when it comes to x != 'q', but since there is ||, program checks all the other conditions and x != 'Q' is true ---> whole condition is true and
while() stuck in an infinite loop
Last edited on
Cool that worked. Thanks guys I understand what I did wrong.
ok so similar problem to before. I tried implementing more do while loops in my code and they work to a certain extent.

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
do{ // #1
    for (vector<string>::iterator t = str1.begin() ; t != str1.end(); ++t)
    {
	do{// #2
        cout << *t<<"\n";
        cout<< "Do you want to accept, replace, delete this value or keep and add to it?\n";
        cin >> d;
        
        if (d == "accept") 
	{
		outfile << *t << "\n";
	}
        	
        if (d == "replace")
	{
		cout<< "what would you like to replace this value with?\n";
		cin >> value2;
		outfile << value2 << "\n";
            
        }
        
        if (d == "delete") 
	{
            cout << "this value has been deleted\n";
        }
        
        if (d == "keep") 
	{
		cout<< "what value would you like to add along with the existing value?\n";
		cin >> value1;
            
		outfile << *t << "\n";
		outfile<< value1 << "\n";
        }
	  }//do ends #2
	while( d != "accept" || d != "replace" || d != "delete" || d != "keep");

	//else
	cout << "Invalid choice\n"; 

	do{// #3
	
	cout<< "Enter q to quit or r to retry: ";
	cin >> y;

  }//do ends #1
	while(y !='q' && y != 'Q' && y != 'r' && y!= 'R');

        }

	  }//do ends #3	
	while(y == 'r' || y == 'R' );
    

    outfile.close();


I don't know what I should do so that my 2nd do while loop exits if the user enters the wrong input.
Last edited on
You've made exactly the same mistake in your logic as you made last time round.

The solution is exactly the same.

And if you made the same mistake twice, I suspect it's because you don't really understand why what you did was wrong. Take some time to understand why your loop wasn't working last time around, and to understand why rich1's suggestion made it work.

Last edited on
As I have said lots of time son this forum, I really hate dislike constructs like this:

1
2
3
4
5
6
7
8
9
10
11
12
 	do{// #3
	
	cout<< "Enter q to quit or r to retry: ";
	cin >> y;

  }//do ends #1
	while(y !='q' && y != 'Q' && y != 'r' && y!= 'R');

        }

	  }//do ends #3	
	while(y == 'r' || y == 'R' );


First your do loops crossover - the end of #1 is in the middle of #3.

This is the bit I dislike: it's error prone, non-scalable & messy:
while(y !='q' && y != 'Q' && y != 'r' && y!= 'R');

If you really do need a do loop, then put the closing while on the same line as the closing brace, so readers don't confuse it for a null while loop:

} while(y == 'r' || y == 'R' ); //do ends #3

When trying to take care of lower & uppercase, make use of the tolower or toupper functions to halve the logic. But the logic is 2 sided : Quit or retry. So you could have a boolean variable called Retry say, if the input is 'N' then the program quits.

Also having an entire word as input which is then tested, is error prone:

if (d == "delete")

If the users enters that word with mixed case, it will fail. Best to stick with a single char as input.

I dislike do loops in this case as well - notice you have the tests twice? Much better with a while loop IMO.

This question is really a simple menu, search for some of the replies I (and others) have made. They use while loops with a switch inside.

I hope this has made it easier :+)
Topic archived. No new replies allowed.