While loop not ending when condition is met - c++

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.

Related

Decide if a sequence (integer numbers) is monotonically increasing

#include <iostream>
using namespace std;
int main()
{
int n;
bool error;
do
{
cout << "How many numbers would you like to put in this sequence? "<< endl;
cin >> n;
error = cin.fail() || cin.peek() != '\n' || (n < 0);
if (error)
{
cout << "Please input again" << endl;
}
cin.clear();
cin.ignore(999,'\n');
}while(error);
int a[n];
cout << "Please input the numbers in your sequence." << endl;
for(int i = 0; i < n; i++)
{
do
{
cin >> a[i];
error = cin.fail() || cin.peek() != '\n';
if (error)
{
cout << "Please input again" << endl;
}
cin.clear();
cin.ignore(999,'\n');
}while(error);
}
for(int i=0; i<n; i++)
{
if (a[i]<a[i+1])
{
cout << "The sequence is monotonically increasing." << endl;
}
else
{
cout << "The sequence is not monotonically increasing." << endl;
}
}
}
Hello guys, I want to check if this sequence (integer numbers) is monotonically increasing or not.
And I do not know which way I should use, so I just choose to use the 'For' loop, which it just compare two numbers each time, which its not comparing all numbers together.
Could you please help me?
Thanks ::>
Your initial attempt using the for loop is on the right track. The key here to fix the message being printed multiple times is to move the print statement (cout << ...) outside the loop. Now, you may ask, "How do I do that?" The proper way to approach it is to negate the condition: how do you know that a sequence is not monotonically increasing? (Based on your code, I will assume you are looking for a strictly increasing sequence.)
You know a sequence is not monotonically increasing if the current term in the sequence is greater than or equal to the next term in the sequence. Once you find one such pair of terms, you immediately know the sequence does not satisfy that property and can exit the loop early. Thus, our tactic to solving the problem is to first assume the condition is true, check if the condition is ever not true for any two elements, and then to check the condition again and print the result.
Thus, your final for loop should look like this:
bool is_increasing = true; // Begin by assuming the condition is true.
for (int i = 0; i < n - 1; ++i) { // Note the condition. More info below.
if (a[i] >= a[i + 1]) { // Here we check if the condition is NOT met.
is_increasing = false;
break; // This exits the loop. We don't have to keep going because
// of the way monotonically increasing is defined.
}
}
// Now we check the condition and present the result.
if (is_increasing) {
cout << "The sequence is monotonically increasing." << endl;
}
else {
cout << "The sequence is not monotonically increasing." << endl;
}
There is another issue with your code. You want to be very careful about not attempting to read past the end of an array. If we trace over the for loop you wrote, what happens when i = n - 1? Clearly, n - 1 < n, so the body of the for loop runs. Then we run into the if statement: if a[i] < a[i + 1]. Okay, the first part a[i] is good because that is really asking for a[n - 1] which is legal, but what about a[i + 1]? Whoops, if n is supposed to be size of the array, then a[n] does not exist! (Remember, arrays are zero-based!) Off-by-one errors are ubiquitous in programming, but if you take the time to trace through the code, you can catch most of them. (Notice how I in the above fixed the issue by changing the loop condition.)
Edit:
As pointed out by paddy in the comments, you do not want to use an array here because that is nonstandard c++. Instead, you want to use the std::vector (or just vector if you are using namespace std) class. Vectors are very similar to arrays, but they can grow and shrink as needed at runtime. The syntax for using them is also a little different. An example of how to use vector follows:
std::vector<int> a {}; // This constructs an empty vector of ints.
a.push_back(1); // This puts 1 at the end of the vector. In this case,
// you can access this number at location 0.
a.push_back(2); // This puts 2 at the end.
cout << print(a.at(0)) << endl; // This will print 1.
cout << print(a.at(1)) << endl; // This will print 2.
You can also use [] like with arrays to access existing elements of the vector, but using .at may be preferable because you get bounds checking.

skip the whole loop without running the while

I have a while loop and I want to skip the whole loop without running the condition in parantheses again becuse as you now, the vector's Size is one greater then their cell number. I mean it is like:
[ Cell 0 ][ Cell 1 ][ Cell 2] --> Size = 3
So I have to skip the whole loop to prevent an Error. I need to write something that takes the program from point A to B without running "while()" My loop:
size = 0;
while ((usernamelog[size] != usrlog || passwordlog[size] != passlog) && size < usernamelog.size())//Checking Username And Password
{
if (x == 2)//Login Unsuccessfull
cout << "Username or Password is Incorrect. Please try again." << endl;
cout << "Enter Your Username: ";
cin >> usrlog;
cout << "Enter Your Password: ";
cin >> passlog;
x = 2;
size++;
if (usernamelog.size() == size)
//Point A
}
//Point B
for example, when usernamelog.size is 2 and size is 2, Jump From A to B
You are looking for break :
After this statement the control is transferred to the statement immediately following the enclosing loop or switch. As with any block exit, all automatic storage objects declared in enclosing compound statement or in the condition of a loop/switch are destroyed, in reverse order of construction, before the execution of the first line following the enclosing loop.
Example:
while (true) {
std::cout << "this loop runs only once";
break;
}
There is an "issue" that comes up sometimes when you have nested loops, so I'll also add it here even not relevant for your code at the moment. Note that break only breaks out of the most inner loop. Once you have more loops you need more than a single break. For example this will run till infinity:
while (true) {
while (true) {
break;
}
}
An easy solution is to put the loops inside a function and to return:
void foo() {
while (true) {
while (true) {
std::cout << "this will be printed only once";
return;
}
}
}
Note that you can do this also for a single loop and often that is the cleaner way.
PS: If you do know the number of iterations beforehand, then it is more idomatic to use a for loop instead. Also consider to fix your conditions such that you do not need to break out of the loop from within the body.

C++ special-value-type loop has to exit when a negative value is entered without using break statement

I just completed a program that has to quit when a negative value is entered as input. Everything is working good except for only one issue, it quits the program after the second time a negative value is entered. After some research I noticed the use of break, however the samples I have to guide the assignment use only if and else statement.
#include <iostream>
using namespace std;
int main()
// insert code here...
// create a variable named "pounds" that can be used to store an integer.
// wait for the user to type in a value and put that value into the variable ounces
{
int poundsTotal;
int ouncesTotal;
while (poundsTotal >= 0)
{
cout << "Enter pounds or a negative number to quit: ";
cin >> poundsTotal;
ouncesTotal = poundsTotal * 16;
cout << poundsTotal << " pouds is " << ouncesTotal << " ounces." <<endl;
cout << " Enter pounds or a negative number to quit ";
cin >> poundsTotal;
poundsTotal++;
}
if (poundsTotal == 0){
cout <<"you enter a zero value" <<"Try onemore time";
}
else {
cout << "you chose to quit the program" <<poundsTotal;
}
}
The condition of a while loop is evaluated after the body has been executed. Then it is determined whether the body will be run again. Change your code and add an if statement inside the loop.
if(poundsTotal < 0) break;
And yes, a break statement is useful in a loop. Otherwise you can't stop the loop before your test condition is evaluated to false.
In your case, I find using a break would be a simple option.
When the program first reaches while (poundsTotal >= 0), poundsTotal has no defined value. This puts you at the mercy of the gods as to whether the program will work as expected or not, and Gods are notoriously unreliable. For more information, look up the term Undefined Behaviour.
The solution to this is ask the user for poundsTotal before the loop and once more at the end of the loop.
If you want to get really posh and do this without repeating code (and stay DRY) , make a function that gets poundsTotal from the user and call this function in the while loop's condition. For example,
while ((poundsTotal = getPoundsTotal()) >= 0)
{
...
}

Program terminates instead of continuing integer input validation loop

I'm asking the user to select a choice between items in a backpack by entering an integer corresponding to the item. But despite my current integer input validation code, the whole program terminates instead of redisplaying the choices and asking the user to enter a choice again. Is there anything problematic in the code below that may be causing this?
int num;
do{
std::cout << "Choose item to use." << std::endl;
for(int i = 0; i < backpack->size(); i++){
std::cout << i+1 << ". " << backpack->at(i) << std::endl;
};
std::cin >> num;
if(!std::cin.fail()){
if(num < 0 || num > (backpack->size())){
std::cout << "Plese enter an integer in range." <<std::endl;
}else{
break;
};
}else{
std::cin.clear();
std::cin.ignore(80, '\n');
std::cout << "Invalid input. Please enter an integer." << std::endl;
};
}while(std::cin.fail() || (num<0 || num > (backpack->size())));
You have to assign an initial value to num. If you don't, it will contain a garbage value, which is possibly less than 0 or greater than backpack->size()-1, which will make the condition true.
int num = 0;
Edit: Scraped last answer
The following clear the cin.fail() flag:
std::cin.clear();
std::cin.ignore(80,'\n');
So upon reaching the loop condition, cin.fail() returns false and the unitialized num most likely contains 0. Thus, your continuation condition does not pass and the loop returns.
As suggested by #Eddge, you should initialize num to an invalid value in regards to your condition, like -1.
After looking over the code a few times, I don't immediately see a problem with the logic, though I could be wrong. But from what I understand is the intention of the code, the condition in the while statement is redundant and unnecessary. You are already checking those same conditions in the if statements and breaking out of the loop when needed, so try using while(true) as your while statement and see if it fixes your problem.
I just found that changing "std::cin.fail()" to "!(std::cin>>num)" in the while condition did the trick. Why do you think that is? By the way, thanks for all of your input!

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

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.