My code uses what I thought would be a simple while loop. It checks if the randCard already exists in the vector I have and, if it does, makes a new randCard.
I've added cout statements within the loop to try to find which processes it's running through and discovered it's only running through the while loop, none of the nested for loops. The problem is as follows:
bool isSame = true;
//Make sure they don't be the same cards
while (isSame){
cout << "While entered" << endl;
for(int i = 0; i < notToUse.size(); i++){
if(randCard == notToUse.at(i)){
randCard = rand() % 24;
}
cout << "First for ran" << endl;
}
for (int i = 0; i < notToUse.size(); i++){
if (randCard == notToUse.at(i)){
cout << "Recheck loop" << endl;
break;
}
else{
cout << "Else ran" << endl;
isSame = false;
}
}
}
randCard is from a class of type Cards. The vector notToUse consists of cards indices that have already been used. The end cout statements end up looking like:
While entered
While entered
While entered
While entered
While entered
It seems like the for loops aren't even accessed. How can I fix this?
For anyone who might stumble upon this, the answer was resolved in the comments. The vector was of size 0, so the for loops didn't even run.
Related
So, let me preface that I am still learning C++ and would appreciate some guidance on what I am doing wrong.
My prompt is to write a function that continuously prompts a user for a valid age (between 0 and
100) and the function must only return the age to the caller of the function after a valid age is retrieved. AND For each function, you must declare the function using a function prototype before main and then define the function after main.
Here is my code,
#include <iostream>
using namespace std;
int num;
bool valid;
int validateInput()
{
cout << "Pick a number between 0 and 100" << endl;
cin >> num;
while(bool valid = false)
{
if(num <= 0)
{
cout << "Error: Number is invalid because it's too low" << endl;
bool valid = false;
return 0;
}
else if (num >= 100)
{
cout << "Error: Number is invalid because it's too high" << endl;
bool valid = false;
return 0;
}
else
{
cout << "You are " << num << " years old." << endl;
bool valid = true;
return 0;
}
}
}
int main()
{
validateInput();
return 0;
}
So I am trying to get my program to work but the IF statements keep getting skipped.
Am I misunderstanding something? Any and all help is very much appreciated.
EDIT: Thank you to Arvin and iammilind for your help.
I was able to fix the code so my while loop condition would actually trigger, moved my cout statements into the loop and so I wouldn't get infinite output.
My final working code looked like this.
#include <iostream>
using namespace std;
int num;
bool valid = false;
int validateInput()
{
while(!valid)
{
cout << "Pick a number between 0 and 100" << endl;
cin >> num;
if(num <= 0)
{
cout << "Error: Number is invalid because it's too low" << endl << endl;
bool valid = false;
}
else if (num >= 100)
{
cout << "Error: Number is invalid because it's too high" << endl << endl;
bool valid = false;
}
else
{
cout << "You are " << num << " years old." << endl;
bool valid = true;
return 0;
}
}
}
int main()
{
validateInput();
return 0;
}
You give a false value to the while loop that makes the while loop doesn't start the loop.
do this instead:
bool valid = false;
while (!valid){ // while valid is still false, do the loop
// your code here
}
Further explanation: You're currently using sentinel-controller loop
reference: https://simplecplusplus.wordpress.com/tag/sentinel-controlled-loop/
In order for while loop to start running, you've to provide the "true" condition to the while, and it will start looping until the condition turn out to false.
Programming tips for you: next time, you've to see the larger picture of your code every time you're trying to debugging. If you're sure the if-else code is running and have no problem, you have to enlarge your investigation for the bug, maybe it's the while loop that didn't work, not if-else. And if the while loop seems having no problem, maybe its the function or the caller of the function
while(bool valid = false) never allows the execution to enter the loop. Hence the if conditions are never called.
Use it as below:
while(valid == false) { // see '==' sign. `while(not valid)` is also fine
// ... your 'if' conditions
}
Actually you are creating a locally scope variable within while() by having a bool before it. So bool valid hides bool ::valid (declared outside).
Also, once the loop ends, you may want to reset it to false again. Otherwise this function will never be able to used again!
Using globals (bool valid) for such functionality is a bad design.
void InputStatisticalData()
{
//variables declaration
cout << "\n[Here to take in data]" << endl;
//cin data
while (exit == false)
{
cout << "Entered Loop" << endl;//for troubleshooting purpose
cout << "CountCheck: " << countcheck << endl;//for troubleshooting purpose
if (!Vector.empty())
{
cout << "Entered Vector check IF" << endl;//for troubleshooting purpose
if (condition)//checks if data has any duplicates
{
cout << "\nData already exist, please enter a new set of data." << endl;
break;
}
else
{
cout << "Entered countcheck++" << endl;//for troubleshooting purpose
countcheck++;
}
}
else
{
//stores data
exit = true;
}
}
}
Hi guys, above is my function to take in some data and store them into an object before storing into a vector. Everything works fine, therefore i decided to do some validation checking for the function. 1 of it is to check if the data keyed in, is it already been keyed in before.
I can store the data once and that's it, once i attempt to store it again, it will go into an infinite loop and give me a segmentation fault. I have been trying to solve it for a week but to no avail.
Another infinite loop is the cin.fail. It goes into an infinite loop as well if a wrong input is detected.
Thanks for taking your time to take a look.
Lol, why keep down-voting my questions, there's a question and a solution, it's suppose to help others, so stop down-voting and upvote it
You are dealing with an infinite loop because the error flags are not reset at the end of your iterations.
You should do a cin.clear() to reset the failbit before attempting any other operations:
if(cin.fail())
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //skip bad input
...
}
On your second loop, you check if the vector of data is empty or not. If it is not empty (a second entry) and your data is new, it will fall indefinitely in the else statement that increases countcheck.
Two things may happen: an infinite loop or a segmentation fault (out of bounds exception).
You should check for an upperbound limit, e.g.:
if(countcheck > Vector.size())
{
//This data is new
PTD.setLD(LD);
Vector.push_back (PTD);
cout << "\nRecord stored successfully, returning back to main menu." << endl;
exit = true;
}
else if(Vector[countcheck].getX() == MainX &&
...
}
You could also use a for statement instead:
for(countcheck = 0; countcheck < Vector.size(); countcheck ++)
{
if(Vector[countcheck].getX() == MainX && ...)
{
...
exit = true;
break;
}
}
//New element
if(countercheck == Vector.size())
{
PTD.setLD(LD);
Vector.push_back (PTD);
cout << "\nRecord stored successfully, returning back to main menu." << endl;
exit = true;
}
I have been trying to fix this program for the past two days and it is proving to be quite troublesome. It is an assignment for my intro to C++ course and has given me nothing but trouble. I have searched this board, posted on Cplusplus.com and spent hours on Google, looking for some assistance.
Here is my problem. I have been given a program and need to add a few features to it:
I have to save the users entries.
I have to display an error message if the user enters the same entry twice.
Seems simple? Not for a beginner such as myself. Here is the code, with what I have attempted to add to it in order to meet the problem's requirements.
int main()
{
//declare variables
string origWord = "";
string letter = "";
char dashReplaced = 'N';
char gameOver = 'N';
int numIncorrect = 0;
string displayWord = "-----";
string letterGuess[26];
//get original word
do //begin loop
{
cout << "Enter a 5-letter word in uppercase: ";
getline(cin, origWord);
} while (origWord.length() != 5);
//clear the screen
system("cls");
//start guessing
cout << "Guess this word: " <<
displayWord << endl;
while (gameOver == 'N')
{
cout << "Enter an uppercase letter: ";
cin >> letter;
//Entry Storage and Error Message. This is my problem.
for (int x = 0; x < 26; x++)
{
letterGuess[x] = letter;
for (int i = x; i < 26; i++)
{
if (i != x)
{
if (letterGuess[x] == letterGuess[i])
{
cout << "Letter already entered. Choose another letter."
<< endl;
}
}
}
}
//search for the letter in the original word
for (int x = 0; x < 5; x += 1)
{
//if the current character matches
//the letter, replace the corresponding
//dash in the displayWord variable and then
//set the dashReplaced variable to 'Y'
if (origWord.substr(x, 1) == letter)
{
displayWord.replace(x, 1, letter);
dashReplaced = 'Y';
} //end if
} //end for
//if a dash was replaced, check whether the
//displayWord variable contains any dashes
if (dashReplaced == 'Y')
{
//if the displayWord variable does not
//contain any dashes, the game is over
if (displayWord.find("-", 0) == -1)
{
gameOver = 'Y';
cout << endl << "Yes, the word is "
<< origWord << endl;
cout << "Great guessing!" << endl;
}
else //otherwise, continue guessing
{
cout << endl << "Guess this word: "
<< displayWord << endl;
dashReplaced = 'N';
} //end if
}
else //processed when dashReplaced contains 'N'
{
//add 1 to the number of incorrect guesses
numIncorrect += 1;
//if the number of incorrect guesses is 10,
//the game is over
if (numIncorrect == 10)
{
gameOver = 'Y';
cout << endl << "Sorry, the word is "
<< origWord << endl;
} //end if
} //end if
} //end while
system("pause");
return 0;
} //end of main function
My only edit to the program is directly under the header of Entry Storage and Error Message. I have tried a single for loop, but that simply displayed the error message for every letter entered. Not only that but it displayed it 26 times. Adding a Break command fixed that and it only displayed once. However, it still displayed on every entry.
A member of Cplusplus, pointed out that I was incorrectly testing the same variable against the array in the same location. That is why it displayed the error on every entry. Now with this loop, the error only displays when an entry is entered twice. However, the error message displays all 26 times once more. On top of that, it will only error if the letters are entered one after another.
For example, if I enter A then X then A again, no error is shown. If I enter, A then A again, the error is displayed 26 times. Something is clearly wrong with how the letter variable is being entered into the array on top of the whatever is causing the error message to display multiple times.
Any amount of assistance would be greatly appreciated.
Edit: My professor has gotten back to me and suggested using the following instead of what I have been tinkering with:
for (int x=0; x<5; x++)
if (origWord[x] == letterEntered)
origWord[x] = '-';
Is it just me, or does this miss the mark completely? I haven't tried converting it into my program as a simple copy and paste job produces compile errors. However, I don't see how that does anything with what I'm trying to do.
This set's all entries of your letterGuess array to the most recently guessed letter.
letterGuess[x] = letter;
This isn't what you want.
You need to think about the actual algorithm you need to implement:
The user enters a guess
Check to see if they've already guessed that letter
If they have, display an error message, return to 1.
If they have not, save that guess, continue with the game logic.
If you have already learned about standard containers, this can be trivially done with a std::set, or a std::vector that has been sorted.
You need to compare each element in the array to the guessed word. Best use a for loop for this. No more needs to be said if this is an assignment.
Also don't use system("cls") in your program, it is a massive security flaw and may lose you marks.
hi im trying to do a while loop, im new to programming and reading online i cant really get my head around it, i have used flag to show that the inputted name matches the name in the data file, i want to do this so that after i know it doesnt match it loops it the whole thing again, i have no clue how to implement this,
{
clrscr();
cout << "This Is The Option To Delete A Record\n";
char yesno;
char search;
char name[21];
int flag = 0;
cout << "Enter Employee Name : ";
Input(name,20);
for (int r=0;r<row;r++)
{
if( strnicmp(name, emp[r].first_name, strlen(name) ) == 0 )
{
flag = 1;
clrscr();
cout << "Employee Number - " << emp[r].employee_number << endl;
cout << "Name - " << emp[r].first_name << " " << emp[r].surname << endl;
cout << "Department Number - " << emp[r].department_number << endl;
cout << "Week Ending Date - " << emp[r].weekend << endl;
cout << "Delete This Record (Y/N)? : ";
Input(yesno);
yesno = tolower(yesno);
if ( yesno == 'y' )
{
emp[r].deleted = true;
cout << "Record Has Been Deleted";
}
else if ( yesno == 'n')
{
cout << "Record Hasn't Been Deleted";
}
}
}
if (flag == 0)
{
cout << "There Are No Matching Records" << endl;
}
pressKey();
}
It's pretty simple, so have a bunch of code you want to keep executing it while a flag is zero, so that's just
int flag = 0;
while (flag == 0)
{
// whole bunch of code
}
That's it, just replace 'whole bunch of code' with the code you've written above.
Implementing this in a while loop would look like this:
bool flag=false;
while(!flag){
...
if(<find a match>) flag=true;
}
Assuming you understand the for loop, I think you can understand the while loop quite easily based on the comparison of for and while.
See, you used a for loop:
for (int r=0;r<row;r++){
// do stuff
}
There are 3 key points here.
int r=0 This is your initial condition.
r<row This is your condition which keeps the loop running.
r++ This is what happens at the end of each iteration of loop.
To rephrase the statements above:
Considering r equals zero initially, while r is less than row, increment r.
Now we can easily see how while loop is striking us:) To implement this, consider the following while loop example:
int r=0; //(1)
while(r<row){ //(2)
//do stuff
r++; //(3)
}
See, now the 2 loops do practically the same thing.
If you want to do operations based on a flag, you can also prefer an infinite loop:
while(1==1){
if(some condition)
break;
}
as well as an infinite for loop:
for(;;){
if(if some condition)
break;
}
Again, 2 loops are practically the same.
so basically, you have a file with some data. And also, you accept some data from the user.
And then you perform a comparison between the appropriate fields of the two sets.
Why would you want to do it all over again once the entire comparison (file process) is done?
if you simply want to run an infinite loop, you can do this:
while(true)
{
//your code
}
you can do same with a for loop also. infact for loop and while loop both are same except for the syntax. i.e. an infinite for loop.
for (int r=0;r<row;r++)
{
if(r==row-1)
{
r=0;
}
}
I guess what you want to do is to, once one set of user input doesn't match the file content, you want to take another set and match it again and so on.
so you don't need an infinite or always executing loop for this.
Just make your comparison module a separate function which should accept the set of user inputs. All you do is accept user inputs and show the result. And give the user an option to re-enter inputs.
Below is simple algo for what you want.
int main()
{
char a='a';
while(a != '~')
{
TakeUserInput();
if(PerformComparison())
{
cout << "Success";
break;
}
}
}
inside TakeUserInput() you do all those cin << to set a global array or set of global variable. also, you cin << a, to terminate program at your will.
and inside PerformComparison(), you do what you have posted here in your question.
I'm a novice to c++ programming and currently taking a class as an introduction to programming. I am currently working on a homework project where I input 10 integers and determine whether the numbers are in ascending order or not.
The issue I'm having is that the program always thinks there is a ascension, no matter the input provided. I figured the problem lies in the IsInOrder() function's for loop, however I can't figure out why exactly it isn't working or how to fix it.
Another potential problem is how to determine ascension for all values, for instance if my code worked I think it would count [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] as an ascension, even though it's not.
I've tried searching online and have found a few similar assignment questions, but with no answer to these problems.
Here's the code I have so far:
#include <iostream>
using namespace std;
bool IsInOrder (int numHold[]);
//This portion takes the numeral inputs and outputs the answer
int main()
{
int numHold[10];
bool status;
cout << "Welcome to the Ascension detector 5000" << endl;
cout << "This program will detect whether the numbers you input are in ascending
order" << endl;
cout << "Isn't that neat?" << endl <<endl;
for (int i=0; i < 10;i++)
{
cout << "Please enter a number: ";
cin >> numHold[i];
}
cout << endl;
for(int i=0;i < 10;i++)
{
cout << numHold[i] << endl;
}
status = IsInOrder(numHold);
if (status == true)
{
cout << "The numbers are in ascending order" << endl;
}
else
{
cout << "The numbers are not in ascending order" << endl;
}
system("PAUSE");
return 0;
}
//This function determines whether the inputs are in ascending order
bool IsInOrder (int numHold[])
{
for (int i = 0; i < 10; i++)
{
if (numHold[i] < numHold [i++])
{
return false;
}
else
{
return true;
}
}
}
Appreciate any help in advance and sorry if the code isn't well formatted, the code wasn't copy/pasting well in to the code sample.
in IsInOrder Function, run for loop till i<9 and remove else part and put return true outside the for loop.
Why return true outside the for loop?
Because return true only when you checked all the element, not every time. Take a look at your code you'll get it.
Your IsInOrder routine doesn't check all the values in the array, it returns immediately after encountering two different numbers.
Also, if it would run through the entire array (i.e. when all the numbers would be the same), it would have checked 11 elements by the time it ended instead of 10, and it wouldn't return anything.
bool IsInOrder(int numHold[])
{
bool inOrder = true;
for (int i = 0; i < 9; i++)
{
if (numHold[i] > numHold[i+1])
{
inOrder = false;
break;
}
}
return inOrder;
}
Firstly, the true and false branches are the wrong way round.
Secondly (assuming true/false has been fixed), you conclude that the entire sequence is in the ascending order as soon as you've seen two numbers that are in order. That's not correct: you can't return true until you've examined every pair.
Lastly, the loop's terminal condition is off by one.
bool IsInOrder(int numHold[]) {
for (int i = 0; i < 9; i++) {
if (numHold[i] >= numHold[i+1]) {
return false;
}
}
return true;
}