Why do some sentinel loops require break to terminate? c++11 - c++

I have a loop that looks something like this
int temp = 0;
int menuItem;
while (temp != -1 && temp < 5)
{
cout << "Order " << temp + 1 << ": ";
cin >> menuItem;
arrayData[temp] = menuItem;
temp++;
break;
}
When I learned to use sentinels, I did not learn them using break...
for example.
int total = 0;
int points;
int game = 1;
cout << "Enter the points for game #" << game << endl;
cin >> points;
while (points !=-1)
{
total += points;
game++;
cout << "Enter the points for game #" << game << endl;
cin >> points;
}
This second loop continues on towards infinity until the value -1 is entered, and then it stops without the need for a break;. My first loop however will not stop when the sentinel value is entered unless the break is included.
Why is that?

While statement always repeat until the set condition get to false. In your first code example
while (temp != -1 && temp < 5)
Here, the while loop will exit if temp is -1 or temp is equal to 5. But, you insert break in your code which is will stop or force your while loop condition to stop.
while (condition) {
// Some code.
// Even if the condition true, it will stop because of break.
break;
}
In your second code, the condition set to
while (points !=-1)
so the while will only stop or exit, if the points variable has value of -1.
After understand the basic, you will find the answer for your question on why on the first while it didn't stop if there is no break;. The answer is because the condition on that while is still true so that the while execute again.

break always breaks the loop when it´s called.
In your first loop, however, you´re reading menuItem, no temp.
So, if you in enter -1 menuItem equals -1, no temp.

Related

How do i get a loop to keep looping until it has checked all index's of an array, while using a random number generator to check the specific index?

I am working on a Tic Tac Toe assignment for my class. And I cannot get the while loop to keep looping after it takes in a search number thats already been removed from the Array. Example ;
string array[] = { "1", "2", "3", "4", "5",} ;
if I search for a 5, and it is in there still, it will change it to a "X". But if I search for a 5 again, it will quit the entire loop instead of just asking for another input. I need it to keep asking for an input and keep checking the input until the entire array has been changed to X's and O's.
I have tried a for loop, while loop, and even bools to keep the loop going until all values have been changed. but nothing is working.
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
string array[] = { "1", "2", "3", "4", "5" };
string search;
bool found = true;
bool keeprunning = true;
while (keeprunning) {
// for(int i = 0; i < 6; i++){
while (found) {
cout << "Enter a character to search for: ";
getline(cin, search);
for (int i = 0; i < 5; i++) {
cout << "Items in the array " << array[i] << endl;
if (search == array[i]) {
found = true;
array[i] = "X";
cout << "\nPresent" << endl;
cout << array[i] << endl;
break;
}
if (i == 4) { // i has to be set to 1 less than the size of the array, so that it only fires after
// the array has been scanned through and the inputted value hasn't been found.
cout << "\nNOT PRESENT.\n";
found = false;
break;
}
if (search != array[0] && search != array[1] && search != array[2] && search != array[3] && search != array[4]) {
keeprunning = false;
cout << "\n\nThere are no more available places to change\n\n";
}
cout << "New array data\n";
for (int i = 0; i < 6; i++) {
cout << array[i] << " ";
}
}
}
}
First of all, the while (keeprunning) loop is adding nothing to the solution. You should take that out.
What's happening is that when you search for a string that is not in the array (e.g. because it has been overwritten with an X) you set found = false. This means that while (found) at the top of the loop is no longer true, so the loop (including prompting the user to input a number) stops running.
Without fully understanding your requirement I suspect you need to do 3 things:
Think about how you DO want to terminate the loop, otherwise, your program could run forever. For example, if you input (for example) a q (for quit) you could detect that, perform a break, and exit the loop.
Look into using continue instead of break. A continue instruction stops executing further code within the loop and goes around the loop again.
Use a do-while loop instead of a while loop. A do-while loop executes at least once and tests whether it should go round again at the bottom of the loop. A while loop depends on some condition being true - that's why you had to initialise the value of found to be true.

While loop not ending when condition is met

void getPlayerRolls(int RollValues[], int& AttemptCount) {
int i = 0;
int FrameNumber = 0;
int RollNumber = 0;
while(RollValues[i] != -1) {
FrameNumber++;
cout << "Frame # " << FrameNumber << endl;
cout << "Roll #1 "
<< " ";
cin >> RollValues[i];
i++;
cout << "Roll #2 "
<< " ";
cin >> RollValues[i];
i++;
cout << endl;
}
}
My expectation is that when a -1 is entered for one of the roll values that the program terminates. I tried to create a while loop that works with an array but I am having trouble determining how to do this.
I removed lines from your function that are not part of the problem, but maybe this will clarify:
while(RollValues[i] != -1) {
cin >> RollValues[i];
i++;
cin >> RollValues[i];
i++;
i++;
}
What is the value of i by the time the loop condition variable is tested?
The first rollvalue entered is read into some place in the array, but then i is incremented, so if you read back from RollValues[i] you read from a different place in memory! Not only that, you never look at the first roll before accepting the second. And then you increment i yet again. By the time you're back at the top of the loop, i has been advanced 3 times, and neither of the entered rolls is ever tested.
You have other issues too, such as
receiving an array has no "size" information associated, so you do not now how big of an array the caller provided. Your code therefore cannot protect against overruning the memory.
in your while loop, you advance 3 times per iteration, so even if your loop condition checks for boundary cases, you still could have walked off the end of the array before getting back to the top of the loop.
Therefore, I suggest the following:
1) pass in the size of your array into your function, or use a safer data structure, such as std::array or std::vector
2) only process a single roll per loop, and check that you're within bounds before advancing.
3) don't advance your index variable until you're done looking at the value in that place that it refers.

Having trouble setting a range a numbers that a user can input

I am writing a program and have everything working fine except the function below. I am curious as to what would work best to make it so that the users inputs for the first loop can only be from 1 - 69, and the second loop from 1 - 26.
I was going to do a do/while loop but got an error as mentioned below.
//***********************************************
//Case 4 lets you input your own lottery numbers*
//***********************************************
void case4()
{
cout << numberprint << endl;
tickettop();
int array_pick[4];
int pballp;
for (int i = 0; i < 5; i++)
{
cout << evalue << i + 1 << space1;
do
{
cin >> array_pick[i];
} while (array_pick > 0 && array_pick <= 69); //Here is where I get an error for array_pick <= 69 (operand types are incompatible ( int * and int))
}
for (int i = 0; i < 1; i++)
{
cout << eball;
cin >> pballp;
}
cout << endl << endl;
ofs << endl;
ticketbottom();
ofs << bar << box << bar << endl;
}
int lottonumber;
ask: //goto label
cin >> lottonumber; //prompt value in console
//if lower than 1 or higher than 69, goto label
if (lottonumber < 1 || lottonumber > 69)goto ask;
People dislike the goto label, but in this case its not a problem. While loops and for loops are there to make the code more understandable and organizable. The goto label wont make your program slow or 'bad', it will just make it harder to organize. Or in this case, easier.
Your code has a number of issues. There are 2 issues with this line:
} while (array_pick > 0 && array_pick <= 69);
Firstly, you are comparing an array to an integer, that's where the compiler error comes from. Secondly, the condition should be the opposite to what it is now: you want the loop to continue until the user enters a correct value, therefore you need the condition to be true if the entered value is out of range, not when it's actually correct.
What you probably mean to do is this:
} while (array_pick[i] < 0 || array_pick[i] > 69);
To check the second input you can use the same do...while construct, just change the condition:
cout << eball;
do
{
cin >> pballp;
} while (pballp < 0 || pballp > 26);
But there are other problems with your code, even though the rest of it is syntactically correct, as far as I can tell.
The first loop will go out of bounds of your array_pick array.
for (int i = 0; i < 5; i++)
i will take values 0, 1, 2, 3 and 4, but the array you're modifying in this loop is defined as int array_pick[4], so there will only be elements with indexes 0, 1, 2 and 3.
The second for is pointless, as the loop will only ever do a single iteration.

How would I get this to repeat without getting stuck on invalid input?

quick question.
How would I get this code to loop itself so that it keeps asking the question, but still allow a different action when a non-numeric input is given?
int main()
{
int temp = 0;
while (temp =1, 10)
{
int amend_numb = -1;
cout << "\nWhich amendment? ";
cin >> amend_numb;
if (amend_numb == 1)
{
cout << "a.\n";
}
if (amend_numb == 2)
{
cout << "b.\n";
}
I attempted to put it into this while statement, however if I enter anything other than an integer into the cin, then it does an infinite loop of constantly repeating the cout statement. Is there any way to get rid of this problem?
while (temp =1, 10)
Although the expression is syntactically correct, it may not perform the way you think:
1. Assign temp to 1.
2. Disregard the value returned from the assignment (because of comma operator)
3. Remaining expression is 10, which is nonzero, so loop continues.
The general rule of thumb is to use a for loop for known quantities of iterations:
for (temp = 1; // assignment
temp < 10; // continuation expression
++temp) // iterator incrementing
{
// loop content
}
When interacting with Users, you want the loop to repeat until an exit condition is satisfied.
unsigned int temp = 0;
while (temp != 0)
{
cout << "Enter amendment number, 0 to quit: ";
cin >> temp;
if (temp > 0)
{
switch (temp)
{
//...
}
}
}
Some people like a forever loop with a break statement:
unsigned int temp = 0;
while (true)
{
cout << "Enter amendment number, 0 to quit: ";
cin >> temp;
if (temp == 0)
{
break; // terminate loop
}
switch(temp)
{
//...
}
}
while (true)
{
//your code
}
simple
and then for your none integer input, you should really do a type cast if you think the user might not provide expected input. Since cin would return a string so you should use string to int cast, something like "stoi" if your compiler supports it or look up c++ string to int I am pretty sure you will get bunch answers.
Edit: if the user might enter anything that is not a number, then you better check for error, put a try and catch statement between the cast, if it fails then tell the user input is not valid.

While won't start loop after y/n input C++

Problem: while doesn't work to start loop over when user inputs y.
I have spent hours searching all forums including Stack Overflow for a clue and tried to figure this out (learning C++ on my own). Based on what I have read I have tried: a do loop works when placed at beginning but it incorrectly calculates by multiplying prior numb entry by next entry factorial (flushing problem?), I tried break and it stops calculation but it also stops without getting to cout <<“Do another?”. I have also tried adding/moving braces around statements and if statements (in desperation).
//problem #6 page 127 Robert Lafore OOP Prg C++ 4th ed.
#include <iostream>
using namespace std;
int main()
{
unsigned int numb;
unsigned long fact = 1; //long for larger numbers
char ch;
cout << "Enter a number ";
cin >> numb;
for (int j = numb; j > 0; j--) //multiply 1 by
{
fact *= j;
cout << "Factorial is "<< fact << endl;
cout << "Do another? (y/n)\n";
cin >> ch;
}
while(ch !='n');
return 0;
}
Your logic isn't quite right - you need to perform the operation once, then ask, and redo the entire operation.
Right now, you do a for loop for your operation, then get the character the user types every loop iteration, then just start a while loop that never terminates.
do/while is a good candidate for this:
do
{
fact = 1; // Reinitialize for subsequent loops
cout << "Enter a number ";
cin >> numb;
for(int j = numb; j > 0; j--) //multiply 1 by
{
fact *= j;
}
cout << "Factorial is " << fact << endl;
cout << "Do another? (y/n)\n";
cin >> ch;
}
while (ch == 'y'); // Switched to make anything other than 'y' break out
You need to do this:
do
{
for(int j=numb; j>0; j--) //multiply 1 by
{
fact *=j;
}
cout <<"Factorial is "<< fact<<endl;
cout <<"Do another? (y/n)\n";
cin >> ch;
}
while (ch != 'n');
What's wrong:
Your code goes into a for loop:
for(int j=numb; j>0; j--)
It calculates the factorial...but the code to do another one is in the for loop! Your program flow is like this:
Enter the for loop
Multiply fact by j and store the value in fact
Print the value of fact
Ask to do another
Store the value in ch
Continue the for loop
See the problem? You are asked to do another for each iteration of the for loop. Then, the while loop does this:
Loop while ch isn't equal to 'n'.
But...the loop is infinite! After the last iteration of the for loop, ch doesn't change. So, if the last value was 'y', well, the while loop keeps on looping over...and over...and over...since it has no body, it just continues forever.
You have sort of the right bits of code, but the bits of code are in the wrong places.
Move the output and input for "Do Another" to after the for-loop.
Add do { before cout << "enter a number;`
Add '} beforewhile(ch != 'n');`
Right now, you have a forever loop when ch is not 'n', since nothing changes ch inside the actual loop.