Checking Errors of Roman Numerals Given A Set of Rules [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So for my comp sci class I was tasked with adding, subtracting, dividing, and multiplying Roman Numerals if they pass 12 rules that I have been given.
I created a 13 element boolean array to keep track of which rules were broken. I created a function called checkErrors, which calls each of the 12 rule checking functions. I call the checkErrors to check each roman numeral before the calculation is done and print out which of the errors is wrong (if any) but instead of just printing out the ones that are wrong it prints each one.
Below is a snippet from checkErrors which is the same for each rule (checkErrorOne, checkErrorTwo...etc.). If the rule is broken, errors[0] is set to false to show that the whole roman numeral is not legal.
`bool checkErrors(string romanNumeral, bool * errors) {
if (checkErrorOne(romanNumeral) == false) {
errors[1] = false;
errors[0] = false;
}
if (checkErrorTwo(romanNumeral) == false) {
errors[2] = false;
errors[0] = false;
}
if (checkErrorThree(romanNumeral) == false) {
errors[3] = false;
errors[0] = false;
}
if (checkErrorFour(romanNumeral) == false) {
errors[4] = false;
errors[0] = false;
}
if (checkErrorFive(romanNumeral) == false) {
errors[5] = false;
errors[0] = false;
}
if (checkErrorSix(romanNumeral) == false) {
errors[6] = false;
errors[0] = false;
}
if (checkErrorSeven(romanNumeral) == false) {
errors[7] = false;
errors[0] = false;
}
if (checkErrorEight(romanNumeral) == false) {
errors[8] = false;
errors[0] = false;
}
if (checkErrorNine(romanNumeral) == false) {
errors[9] = false;
errors[0] = false;
}
if (checkErrorTen(romanNumeral) == false) {
errors[10] = false;
errors[0] = false;
}
if (checkErrorEleven(romanNumeral) == false) {
errors[11] = false;
errors[0] = false;
}
if (checkErrorTwelve(romanNumeral) == false) {
errors[12] = false;
errors[0] = false;
}
if (errors[0] == true)
return true;
else if (errors[0] == false)
return false;
}
`
to return the value of the first element to say if it is legal.
After this when I go to print each rule that was broken I use the following:
void printFunction(string romanNumeral1, string romanNumeral2, string mathOperator, bool errors[]){
if (checkErrors(romanNumeral1, errors) == false && checkErrors(romanNumeral2, errors) == true){
cout << romanNumeral1 << " is illegal becasue" << endl;
if (errors[1] == false)
cout << "Contains a letter that is not M, D, C, L, X, V, or I;" << endl;
if (errors[2] == false)
cout << "I is not followed by I, V, or X;" << endl;
if (errors[3] == false)
cout << "X is not followed by I, V, X, L, or C;" << endl;
for each of the 12 rules. It is printing out every one of the errors, not each one that is wrong.
If someone could help with my logic it would be greatly appreciated.
void printFunction(string romanNumeral1, string romanNumeral2, string mathOperator, bool errors[]){
if (checkErrors(romanNumeral1, errors) == false && checkErrors(romanNumeral2, errors) == true){
cout << romanNumeral1 << " is illegal becasue" << endl;
if (errors[1] == false)
cout << "Contains a letter that is not M, D, C, L, X, V, or I;" << endl;
if (errors[2] == false)
cout << "I is not followed by I, V, or X;" << endl;
if (errors[3] == false)
cout << "X is not followed by I, V, X, L, or C;" << endl;
Edit: Why does the code I wrote print out each of the 12 errors I created instead of only printing out the ones that were violated?
Thanks

Off-topic: Your program can be simplified by having an array of error messages.
The if statement ladder would be replaced by a loop:
for (unsigned int i = 0U; i < MAXIMUM_ERROR_TYPES; ++i)
{
if (errors[i])
{
std::cout << error_messages[i];
}
}
Since there is less code, there will be less possibility of injected defects.

Ok, first of all, you didn't post your checkErrors code, so i am assuming here.
I think that you defined is as
bool checkErrors(string, bool errors[13]){
which means, that it does not take a pointer, but a copy of the 13 booleans. So they get modified within your function, but not outside it. Change it to:
bool checkErrors(string, bool* errors){
ps. Next time, please think about how people with no knowledge about your poblem will understand it. Saves you a lot of flak ;)

Related

vector, removing object trouble

I am new to c++ and am currently learning sfml.
I have set up a system that adds one 'Snowpile' object to the vector. But when I keep hitting errors like "can't increment vector past iterator past end" or that it's outside the scope.
std::vector<Snowpile*> snowpiles;
I want it to check every snowpile for the removed2 bool, and delete the ones that do have it.
for (auto s_it = snowpiles.begin(); s_it != snowpiles.end(); s_it++) {
int sindex = std::distance(snowpiles.begin(), s_it);
if (snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == false) {
snowpiles[sindex]->melting = true;
}
else if (snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == true) {
snowpiles[sindex]->melting = true;
}
else if (!snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == true) {
snowpiles[sindex]->melting = false;
}
snowpiles[sindex]->meltedrem(sindex, snowpiles, m_win);
if (snowpiles[sindex]->removed2 == true)
{
cout << "Detected removed 2 at " << sindex << endl;
//delete snowpiles[sindex];
snowpiles.erase(snowpiles.begin() + sindex - 1);
}
}
The melting parts determine whether the player is on top of a snowpile. The meltdrem functions checks for bool 'melting' == true and then proceeds to start the timer. After a few seconds (+ animations) it sets the bool removed2 to true.
I know that at the program at least sees the bools changing, so thats not it.
Am I simply using vector wrong, or do I need to change something in my loop?
The loop is located in the while(window.isOpen()) loop in int main.
For starters it is unclear why there is used the expression
snowpiles.erase(snowpiles.begin() + sindex - 1);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
instead of
snowpiles.erase(snowpiles.begin() + sindex);
^^^^^^^^^^^^^^^^^^^^^^^^^^
if in a comment you wrote
//delete snowpiles[sindex];
You need to increase the iterator in the for loop only when a current object was not removed.
Change the loop the following way
for (auto s_it = snowpiles.begin(); s_it != snowpiles.end(); ) {
//...
if (snowpiles[sindex]->removed2 == true)
{
cout << "Detected removed 2 at " << sindex << endl;
//delete snowpiles[sindex];
s_it = snowpiles.erase( s_it );
}
else
{
++s_it;
}
}

What is causing zsh:segmentation fault in this case?

this is my first every time posting a question on stackoverflow so I apologize beforehand If my question seems messy. I have a class named token, and a derived class from it called function, integer, and operator. Token has a public variable of type int called _type. I assigned different _type values for each derived classes. The type for integer is 1, 2 for operator, and 3 for function. The purpose of this is so that I can implement different operations depending on the type encountered. I made an rpn function and in it I have something like this.
double RPN::rpn(){
Stack<Token*> rpn_stack;
while(input_q.empty() == false){
if(input_q.front()->_type == 1){
rpn_stack.push(input_q.pop());
}
if(input_q.front()->_type == 2){
double x = rpn_stack.pop()->value();
double y = rpn_stack.pop()->value();
//cout << x << y;
char i = input_q.pop()->op();
if(i == '*'){
double result;
result = x * y;
rpn_stack.push(new Integer(result));
}
}
if(input_q.front()->_type == 3){
input_q.pop();
rpn_stack.push(new Integer(_val));
}
}
return rpn_stack.top()->value();
}
after testing it a couple of times, I found out that the zsh:segmentation fault problem is caused by the input_q.pop() in
if(input_q.front()->_type == 3){
input_q.pop();
rpn_stack.push(new Integer(_val));
}
However, the code works if I change the order of the if statements like this
double RPN::rpn(){
Stack<Token*> rpn_stack;
while(input_q.empty() == false){
if(input_q.front()->_type == 3){
input_q.pop();
rpn_stack.push(new Integer(_val));
}
if(input_q.front()->_type == 1){
rpn_stack.push(input_q.pop());
}
if(input_q.front()->_type == 2){
double x = rpn_stack.pop()->value();
double y = rpn_stack.pop()->value();
//cout << x << y;
char i = input_q.pop()->op();
if(i == '*'){
double result;
result = x * y;
rpn_stack.push(new Integer(result));
}
}
}
return rpn_stack.top()->value();
}
which leads me to question whether the problem was input_q.pop() in the first place. It also works if I were to assign input_q.front()->_type to a static variable inside the while loop like this
double RPN::rpn(){
Stack<Token*> rpn_stack;
while(input_q.empty() == false){
int type = input_q.front()->_type;
if(type == 1){
rpn_stack.push(input_q.pop());
}
if(type == 2){
double x = rpn_stack.pop()->value();
double y = rpn_stack.pop()->value();
//cout << x << y;
char i = input_q.pop()->op();
if(i == '*'){
double result;
result = x * y;
rpn_stack.push(new Integer(result));
}
}
if(type == 3){
input_q.pop();
rpn_stack.push(new Integer(_val));
}
}
return rpn_stack.top()->value();
}
At this point I am very confused as to what is causing zsh:segmentation fault when using the first version. Im wondering if the problem lies in accessing input_q.front()->_type? I could just use the second and third version but I really want to know what is causing zsh:segmentation fault on the first version. If it helps, here is the simple program I wrote to test it. I am also using stack and queue if it helps.
Queue<Token *> postfix;
postfix.push(new Integer(3));
postfix.push(new Integer(5));
postfix.push(new Operator("*"));
RPN rpn(postfix);
cout << "3 5 *: " << rpn() << endl;
cout << "-------------" << endl;
Queue<Token *> postfix2;
postfix2.push(new Integer(3));
postfix2.push(new Function("X"));
postfix2.push(new Operator("*"));
rpn.set_input(postfix2);
cout << "3 x *: (x=3): " << rpn(3) << endl;
the rpn function is called using the () operator in the RPN class. the RPN class has a private variable called _val that is assigned a value to by the () operator. Hope the information Ive provided is enough. Thank you for your time, would appreciate the input!
With reference to your first code snippet, when you say this:
if(input_q.front()->_type == 1){
rpn_stack.push(input_q.pop());
}
if(input_q.front()->_type == 2){
...
You don't check if there's anything left on the input queue the second time you call input_q.front.
A simple fix is to insert a continue statement, like this:
if(input_q.front()->_type == 1){
rpn_stack.push(input_q.pop());
continue;
}
...
You will then loop back to the while statement which checks whether the queue is empty before proceeding.
There are other places in the code where you need to make a similar change, but you get the idea.

Is There A Way To Make These Variables Switch From True To False, Or Am I Doing It Wrong [duplicate]

This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Closed 3 years ago.
I am trying to build a program that allows for the simplification of the stage selection procedures in Smash.
The main Way I am trying to allow the user to ban stages is to set a series of Boolean functions that they set as true or false so that illegal stages will never show up.
The problem is, the Boolean variables I have in the function will not change from true to false.
the "Aban1" function is just supposed to take in the first ban, and make the variable associated with that stage as false. (this is not working and the source of the problem)
The "stagespitter function compares the boolean variables to another set that has already been set up by the user. it only outputs the stages if both the preset stage is true, and the stage that is able to be banned is true.
I have tried enumerated data types, although I think that was the wrong way to attempt this, as visual studio says that enums aren't modifiable variables.
void Aban1(string ban1, bool PS2, bool PS1, bool BF, bool FD, bool SMASHVILLE, bool KALOS, bool TOWN, bool LYLAT, bool STORY, bool ISLAND);
void stagespitter(bool LYLAT, char chLylat, bool chPS1, bool PS1, bool PS2, char chPS2, char chBF, bool BF, char chFD, bool FD, char chIsland, bool ISLAND, char chStory, bool STORY, char chTown, bool TOWN, char chKalos, bool KALOS, char chSmashville, bool SMASHVILLE); //spits out the stages that are available
void Aban1(string ban1, bool PS2, bool PS1, bool BF, bool FD, bool SMASHVILLE, bool KALOS, bool TOWN, bool LYLAT, bool STORY, bool ISLAND) { //this should run the s
if (ban1 == "PS2" || ban1 == "ps2" ) {
PS2 = false;
cout << "Banned ps2" << endl;
}
else if (ban1 == "PS1" || ban1 == "ps1") {
PS1 = false;
}
else if (ban1 == "BF" || ban1 == "bf" || ban1 == "bF") {
BF = false;
}
else if (ban1 == "Smash" || ban1 == "smash") { //remember to set direction for this, as you have to type specifically
SMASHVILLE = false;
}
else if (ban1 == "Kalos" || ban1 == "kalos") {
KALOS = false;
}
else if (ban1 == "Town" || ban1 == "town") {
TOWN = false;
}
else if (ban1 == "FD" || ban1 == "fd" || ban1 == "fd") {
FD = false;
}
else if (ban1 == "story" || ban1 == "Story") {
STORY = false;
}
else if (ban1 == "Lylat" || ban1 == "lylat") {
LYLAT = false;
} //make the final else loop it back
else (ban1 == "Island" || ban1 == "island"); { //instead of running this over and over, make a function that compares the state of true and false of the bools and the functions associated with the stage
ISLAND = false; //and compares them only returning if both they accepted a stage, and it aint false, or not banned yet
}}
void stagespitter(bool LYLAT, char chLylat, bool chPS1, bool PS1, bool PS2, char chPS2, char chBF, bool BF, char chFD, bool FD, char chIsland, bool ISLAND, char chStory, bool STORY, char chTown, bool TOWN, char chKalos, bool KALOS, char chSmashville, bool SMASHVILLE) {
cout << "the Available stages are" << endl;
if (lylat(chLylat) == LYLAT && LYLAT == true) //set the bools equal to the function
cout << "Lylat Cruise" << endl;
if ((ps1(chPS1) == PS1) && (PS1 == true))
cout << "Pokemon Stadium 1" << endl;
if ((ps2(chPS2) == PS2) && (PS2 == true))
cout << "Pokemon Stadium 2" << endl;
if (battlefield(chBF) == BF && BF == true)
cout << "Battlefield" << endl;
if (finalDestination(chFD) == FD && FD == true) //something wrong here not adding up
cout << "Final Destination" << endl;
//not correctly orienting what is false, and giving stages that have already been delcared not valid
if (yoshisIsland(chIsland) == ISLAND && ISLAND == true)//check the set equal parameters
cout << "YoShi's Island" << endl;
if (yoshisStory(chStory) == STORY && STORY == true)
cout << "Yoshi's Story" << endl;
if (townAndCity(chTown) == TOWN && TOWN == true)
cout << "Town and City" << endl;
if (kalos(chKalos) == KALOS && KALOS == true)
cout << "Kalos" << endl;
if (smashville(chSmashville) == SMASHVILLE && SMASHVILLE == true)
cout << "Smashville" << endl;}
I want the boolean variables to be able to be set as false, right now they are not being set as false. I will also later need to reset the variables to true, but I am not at that point yet.
I am going to assume that you are calling ABan1() then stageSplitter() somewhere one after the other. In C++ when you call function, the parameters make all new copies of themselves, then when the function ends, they all disappear. This is called call by value. The booleans will be set in the function, but once the function ends they will not be set anymore. To fix this you can use a call be reference by putting a & before all of your parameters. This will change the original values that you used as parameters in your function. Here is a link that may help explain it a bit better:
https://www.javatpoint.com/call-by-value-and-call-by-reference-in-cpp
Hope this helps!!

C++ returning bool is always false?

I implemented a Quiz Code and did a short change at the end of it to check if the User answered it correctly.
My if / else looks like this:
if (answer == rightanswer){
rightA = true;
}
else {
rightA = false;
}
return rightA;
I already checked with the debugger that if the correct answer is entered it goes to rightA = true; and to return, so this works finde.
But if i check the value of rightA it's false.
If it's needed, here is the function that i use to call the Quiz:
void gameOver(char field[HEIGHT][WIDTH], char newField[HEIGHT][WIDTH]){ // TODO
bool rightA = false;
showQuizDialog(rightA);
do{
system("cmd /c cls");
switch (rightA){
case true : cout << "menu"; menu(field, newField); break;
case false : showQuizDialog(rightA); break;
default : cout << " ";
}
}while(rightA == false);
}
I'm a bit hintless. I may have some logic failure in it i just don't see at the moment.
Greetings
E: I don't wanted to bomb you guys with code. But here is it:
bool showQuizDialog(bool rightA){
Quiz* quiz = Quiz::getInstance();
quiz -> askQuestion(rightA);
return rightA;
}
And the full askQuestion:
bool Quiz::askQuestion(bool rightA) {
int fragenID = rand() % this->fragen.size(); //zufällige Fragen auswählen
struct Question frage = this->fragen.at(fragenID);
std::cout << frage.frage.c_str() << std::endl << endl; //Frage stellen
int rightanswer = this->listAnswers(frage.antworten);
int answer = this->readAnswer(0, frage.antworten.size() - 1);
if (answer == rightanswer){
rightA = true;
}
else {
rightA = false;
}
return rightA;
}
Is showQuizDialog(rightA) supposed to magically change the value of rightA? (I'm assuming you're not passing it by reference).
Did you mean to write rightA = showQuizDialog(rightA) or rightA = quiz -> askQuestion(rightA)?
Also, in your switch that switches on a bool, do you expect any other values than a true or a false?
Your showQuizDIalog is a call-by-value function. So always store the return value of the function into rightA, when calling showQuizDialog, that is :
rightA = showQuizDialog(rightA);
Otherwise, change your function declaration to allow pass-by-reference, maybe like this
showQuizDialog(&rightA);
and no need to return anything from the function(just use a pointer instead of a variable rightA inside the function)

C++ returning boolean as 95

Problem with returning booleans in c++..
bool find( const TrieNode &node, const string word )
{
if (word.length() == 0)
{
if (node.isWord)
{
cout << "TRUE" << endl;
return true;
}
else
{
cout << "FALSE" << endl;
return false;
}
}
char firstletter = word.at(0);
int index = firstletter - 'a';
if (node.letters[index] == NULL)
{
return false;
}
else
{
find (*node.letters[index],word.substr(1,(word.length() - 1)));
}
}
in my main I have
cout << find(*mynode,"word") << endl;
would yield to :
FALSE
95
clearly, a cout of FALSE means that the function returns false.. However, when I print out the result of the function, I get 95 which evaluates to true.. Any reason why it could be doing this?
thanks
Your missing a final return statement, so your getting whatever is in the low byte of EAX, which is random garbage. your probably want return true; at the very end of your function.
Your should pump the warning level of your compiler as it should be telling you this (something along the lines of "not all control paths return a value").
The problem is with your final if statement:
if (node.letters[index] == NULL) {
return false;
}
else {
//if execution gets here, the return value of the function is undefined
find (*node.letters[index],word.substr(1,(word.length() - 1)));
}
...perhaps try:
if (node.letters[index] == NULL) {
return false;
}
else {
return find (*node.letters[index],word.substr(1,(word.length() - 1)));
}