C++ function missing after change in main - c++

Just for clarification, currently using Repl.it. If this problem is due to Repl.it, that'll be it.
I am trying to make multiple state machines that influence each other through different states (Happy, Sad, or Mad). Each machine can talk: say what state they're in; or interact with a different machine, thus changing one of the machine's states;
The problem I have with my code is the everyone function, allowing every state machine in an array to say their states. Whenever something is changed in the main function, the everyone function just doesn't run anymore. I'm sorry that this post is really long, mostly due to any omissions causes the function to break.
This is my code:
using namespace std;
enum Mood {Happy, Sad, Mad, Default};
class StateMac {
Mood state; //The machine's current state
/* Other methods no shown */
//Returns a string relative to their current state
string talk() {
switch(state) {
case Happy : return "I'm happy!";
case Sad : return "I'm sad...";
case Mad : return "I'm Mad!!!";
case Default : return "...";
}
}
//Compares the states between two machines
bool compare(StateMac aStateMachine) {
if (state == aStateMachine.getState()) {
return true;
}
return false;
}
};
//Gets size of a state machine array by comparing each to a default machine
int getSMarSize(StateMac SMar[]) {
int counter = 0;
for (int i = 0; i < 100; i++) {
if (SMar[i].compare(StateMac())) {
break;
} else {
counter += 1;
}
}
return counter;
}
//Receives an array of state machines and makes each of them say their states,
void everyone(StateMac SMar[]) {
for (int i; i < getSMarSize(SMar); i++) {
cout << "SM" << i << ": " << SMar[i].talk() << endl;
}
}
int main() {
//Array with 4 state machines
StateMac ar[] = {StateMac(Happy), StateMac(Sad), StateMac(Mad), StateMac()};
//Have everyone say their states
everyone(ar);
//Does same as above but line-by-line for each machine
cout << "SM0: " << ar[0].talk() << endl;
cout << "SM1: " << ar[1].talk() << endl;
cout << "SM2: " << ar[2].talk() << endl;
//Other functions
string response = ar[0].interact(&ar[2]);
cout << "SM0 to SM1: " << response << endl;
cout << "SM1: " << ar[1].talk() << endl;
response = ar[0].interact(&ar[2]);
cout << "SM0 to SM2: " << response << endl;
cout << "SM2: " << ar[2].talk() << endl;
response = ar[1].interact(&ar[2]);
cout << "SM0 to SM2: " << response << endl;
cout << "SM0: " << ar[0].talk() << endl;
cout << "SM1: " << ar[1].talk() << endl;
cout << "SM2: " << ar[2].talk() << endl;
}
Producing this result:
SM0: I'm happy! //From everyone function
SM1: I'm sad...
SM2: I'm Mad!!!
SM0: I'm happy! //From line-by-line
SM1: I'm sad...
SM2: I'm Mad!!!
SM0 to SM1: There's nothing to be mad about! //Other functions
SM1: I'm sad...
SM0 to SM2: That guy!!!
SM2: I'm happy!
SM0 to SM2: You look happy, might as well forget about that.
SM0: I'm Mad!!!
SM1: I'm sad...
SM2: I'm happy!
Everything looks good in the result as of now. However, if I am to add, change, or delete any line in the main function, all of a sudden, the everyone function doesn't run anymore.
For example, I changed one of the responses in the main function:
everyone(ar);
cout << "SM0: " << ar[0].talk() << endl;
cout << "SM1: " << ar[1].talk() << endl;
cout << "SM2: " << ar[2].talk() << endl;
string response = ""; //Changed here
cout << "SM0 to SM1: " << response << endl;
cout << "SM1: " << ar[1].talk() << endl;
response = ar[0].interact(&ar[2]);
cout << "SM0 to SM2: " << response << endl;
cout << "SM2: " << ar[2].talk() << endl;
response = ar[1].interact(&ar[2]);
cout << "SM0 to SM2: " << response << endl;
cout << "SM0: " << ar[0].talk() << endl;
cout << "SM1: " << ar[1].talk() << endl;
cout << "SM2: " << ar[2].talk() << endl;
Creating this result, notice the missing everyone function call:
SM0: I'm happy! //Line-by-line
SM1: I'm sad...
SM2: I'm Mad!!!
SM0 to SM1: //Changed response
SM1: I'm sad...
SM0 to SM2: There's nothing to be mad about!
SM2: I'm happy!
SM0 to SM2: You look happy, might as well forget about that.
SM0: I'm happy!
SM1: I'm sad...
SM2: I'm happy!

The problem is in your function
void everyone(StateMac SMar[]) {
for (int i; i < getSMarSize(SMar); i++) {
cout << "SM" << i << ": " << SMar[i].talk() << endl;
}
}
This code does not initialize the variable i, and so it has undefined behavior. Changing this to int i = 0 should solve your problem.
BTW, I am also puzzled by your use of the function int getSMarSize(StateMac SMar[]) to determine the size of the array of state machines. Your strategy seems to be to leave a "blank" state machine at the end of the array and counts the array length by iterating until it finds this blank state machine, much like the terminating character in a C string. Since you cannot automatically enforce that the array should end in StateMac(), unlike C/C++ can do with a C string, this is error-prone. There is no good reason to use this technique for an array in C++ -- you should either pass the length of the array as a parameter to the function, or better yet use the std::vector container.

Related

c++ fstream only outputting one case

void budgetCheck() {
for (int i = 0; i != 100; i++) {
if (arrayTotalCost[i][2] > arrayTotalCost[i][0]) {
outputValidPackage(i);
}
else outputInvalidPackage(i);
}
}
void outputValidPackage(int i) {
fstream validPackage;
if (validFirst = false) {
validPackage.open("requestOutValid.txt");
validFirst == true;
}
validPackage << "Total cost is : " << arrayTotalCost[i][0] << " , the budget is : " << arrayTotalCost[i][2] << endl;
validPackage << "The Sydney to Tokyo flight is on day " << flightTicketArray[i][1] << " and costs " << flightTicketArray[i][3] << endl;
validPackage << "The Tokyo to Sydney flight is on day " << flightTicketArray[i][2] << " and costs " << flightTicketArray[i][4] << endl;
validPackage << "A " << hotelArray[i][3] << " star hotel, from day " << hotelArray[i][1] << " to " << hotelArray[i][2] << " will cost " << hotelArray[i][4] << endl;
}
void outputInvalidPackage(int i) {
fstream invalidPackage;
if (invalidFirst == false) {
invalidPackage.open("requestOutInvalid.txt");
invalidFirst = true;
}
invalidPackage << "Package is invalid" << endl << endl;
}
The goal of the code is to take in requests from a text file, and then output the valid and invalid requests into separate text files.
Everything else in the code is working.
I would expect 100 cases between the two text files. But only one is outputting. I am not sure why, the outputted case is seemingly random but the same one every time. The 92nd case. It is not the last valid package or the first invalid. Though it is a valid case.
EDIT : changed = to == . Now one case is printed to both files.

how do i stop repeating answers in this?

i am trying to code a family feud type game and I want to know how do I stop repeated answers? like in this code i could keep writing "bugs" and the loop would just carry on.
void f()
{
int y=0;
string q[17];
string ans1[4];
ans1[0]= "bears";
ans1[1]="bugs";
ans1[2]= "snakes";
ans1[3]="skunks";
string ans;
int sum=0;
q[0]="Name something you try to avoid when camping in the woods.";
cout << q[0] << endl;
for (int a=0; a<7; a++)
{
int b;
getline(cin,ans);
if (ans==ans1[0]||ans==ans1[1]||ans==ans1[2]||ans==ans1[3])
{
if (ans==ans1[0])
{
b=42;
cout << "SURVEY SAYS " << b << "! Good Job! " << endl; sum=sum+b;
}
else if (ans==ans1[1])
{
b=33;
cout << "SURVEY SAYS " << b << "! Nice one man! " << endl; sum=sum+b;
}
else if (ans==ans1[2])
{
b=20;
cout <<"SURVEY SAYS " << b << "! Fantastic man!"<< endl; sum=sum+b;
}
else if (ans==ans1[3])
{
b=5;
cout << "SURVEY SAYS " << b << "! You Got it!" << endl; sum=sum+b;
}
}
else if (ans!=ans1[0]&&ans!=ans1[1]&&ans!=ans1[2]&&ans!=ans1[3])
{
cout << "YOU GOT THIS ONE WRONG! "<< endl; y++;
if (y==3) { cout << "LOOOOSER" << endl; break;}
}
}
cout << " your total score for
this round is " << sum << endl;
}
You'd need to keep a list (I'd recommend std::vector) of all the accepted answers. Then, when given a new answer, you'd need to check it isn't in the list.
Alternatively, for each answer, have an wasUsed variable which you check when the answer is given and set after an answer is accepted.

C++ assignment help on creating codes for reusability?

I've been having trouble doing this assignment. I'm just having a hard time understanding and I am not entirely sure what to do. I've researched and watched videos and havent been able to find the right, specific information. Its a bunch of questions, so I hope someone can not only giveme the answers, but also explain to me so I have a strong understanding :) . Here are the questions:
1)In this exercise we have been given some program code that will accept two integers as inputs
and evaluate which one holds the larger value. This evaluation occurs in multiple places
throughout the code. Write a function that the program could use to perform this same evaluation
instead of duplicating the code over and over. Start by writing a suitable function declaration
towards the beginning of the code file. You will have to decide whether your function will return
some output or not.
2) With your declaration written proceed to define the function, including the appropriate pieces of
code that will evaluate which of the two integers is the largest. If you stated earlier that your
function will return a value, be sure to define what it will return here.
3) Use your result from parts (1) and (2) to reduce the amount of duplicate code in the main function
provided by replacing the multiple instances of the integer comparison with a call to invoke the
function you have created. Remember that the function will require two integers to be passed in
as arguments and if you are returning some value from the function it should be used (stored in
a variable, outputted to screen, etc.). As a word of advice, test your function works correctly after
replacing just one of the evaluations, don’t replace them all at once (if the function works correctly
for the first replacement then it should work for the others).
4) Since the function you have created only compares the values of its parameters and doesn’t write
to them (i.e. change the value stored in them) we should specify in the function declaration and
definition that these parameters should be treated like constants. Make the necessary
modifications to the function and test again to verify the function still works. Confirm the function
will not let you change the data of the parameters by trying to include an operation in the function
that would change the value of one of the variables (e.g. number2 += 10;)
-- Here is the code ( I apologise for the long writing):
#include <iostream>
int main(void)
{
using std::cout;
using std::cin;
using std::endl;
int nNum1 = 10, nNum2 = 11;
cout << "This program will compare two numbers and report which one is larger.\n\n"
<< "Proceeding with evaluation...\n" << endl;
cout << "\nUsing numbers: " << nNum1 << " and " << nNum2 << ", the larger one is: ";
if (nNum1 > nNum2)
cout << nNum1 << endl;
else if (nNum1 < nNum2)
cout << nNum2 << endl;
else
cout << "Neither of them! It's a draw." << endl;
int numberA = 234;
int numberB = 234;
cout << "\nUsing numbers: " << numberA << " and " << numberB << ", the larger one is: ";
if (numberA > numberB)
cout << numberA << endl;
else if (numberA < numberB)
cout << numberB << endl;
else
cout << "Neither of them! It's a draw." << endl;
int one = 'a';
int two = 'A';
cout << "\nUsing numbers: " << one << " and " << two << ", the larger one is: ";
if (one > two)
cout << one << endl;
else if (one < two)
cout << two << endl;
else
cout << "Neither of them! It's a draw." << endl;
cout << "\nUsing numbers: " << 13 << " and " << 84 << ", the larger one is: ";
if (13 > 84)
cout << 13 << endl;
else if (13 < 84)
cout << 84 << endl;
else
cout << "Neither of them! It's a draw." << endl;
int input1 = 0;
int input2 = 0;
cout << "\nPlease enter a number: ";
cin >> input1;
cout << "\nPlease enter a second number: ";
cin >> input2;
cout << "\nUsing numbers: " << input1 << " and " << input2 << ", the larger one is: ";
if (input1 > input2)
cout << input1 << endl;
else if (input1 < input2)
cout << input2 << endl;
else
cout << "Neither of them! It's a draw." << endl;
cout << "\n\tThank you for running me :3\n" << endl;
return 0;
}
You basically have to refactor the code to replace the duplicate code part in your main function.
If you look closely you will see that code like this repeats:
cout << "\nUsing numbers: " << nNum1 << " and " << nNum2 << ", the larger one is: ";
if (nNum1 > nNum2)
cout << nNum1 << endl;
else if (nNum1 < nNum2)
cout << nNum2 << endl;
else
cout << "Neither of them! It's a draw." << endl;
So put that into a function:
void CompareNumbers(int nNum1, int nNum2)
{
cout << "\nUsing numbers: " << nNum1 << " and " << nNum2 << ", the larger one is: ";
if (nNum1 > nNum2)
cout << nNum1 << endl;
else if (nNum1 < nNum2)
cout << nNum2 << endl;
else
cout << "Neither of them! It's a draw." << endl;
}
And call this in your main function instead of duplicating the said code block.

How can I delete a element from a vector?

I'm developing a simple console based email application.
In my app, messages are stored in std::vector, and I want to add possibility to delete messages.
How can I delete a element from a vector?
Here's my code:
//MAIN MENU OPTION 1 SELECTED:
// print list of all messages to the console
void viewInbox() {
vector<Message> inbox{
Message("jayleno#hotmail.com", "Knife you tonight", "Hey Sam, what kind of suit do you wanna be buried in?!"),
Message("paypalservices#hotmail.com", "Urgent from paypal.com", "Dear paypal user, someone has hacked your account. Give us your password now so we change it!"),
};
cout << "You have " << inbox.size() << " new messages.\n";
cout << "Index Subject" << '\n';
for (int i = 0; i < inbox.size(); ++i)
std::cout << "Message " << i << ": " << inbox[i].getSubject() << '\n';
cout << "Please enter number of message you would like to view\n";
int read;
cin >> read;
cout << "From: " << inbox[read].getAddress() << '\n';
cout << "Subject: " << inbox[read].getSubject() << '\n';
cout << inbox[read].getMessageText() << '\n';
cout << "To erase this message press 1\n";
//Code here for deleting a message...
}//end of viewInbox()
To erase a message from the vector use vector::erase which takes an iterator.
The easiest way to get an iterator to a particular message is to use inbox.begin() + message_number.
I have refactored your code into smaller functions to make the code easier to work with:
void viewMessage(vector<Message>& messages, size_t message_number) {
vector<Message>::iterator message = messages.begin() + message_number;
cout << "From: " << message->getAddress() << endl;
cout << "Subject: " << message->getSubject() << endl;
cout << message->getMessageText() << endl;
cout << "To erase this message press 1\n";
int erase;
cin >> erase;
// Maybe do some error checking on cin...
if (erase == 1) {
messages.erase(message);
}
}
void viewMessages(vector<Message>& messages){
auto inbox_size = messages.size();
cout << "You have " << inbox_size << " new messages.\n";
cout << "Index Subject" << '\n';
for (size_t i = 0u; i != inbox_size; ++i) {
std::cout << "Message " << i << ": " << messages[i].getSubject() << '\n';
}
cout << "Please enter number of message you would like to view\n";
size_t message_number;
cin >> message_number;
// Maybe do some error checking on cin...
// And some bounds checking of message_number...
viewMessage(messages, message_number);
}
void viewInbox() {
vector<Message> inbox{
Message{ "jayleno#hotmail.com", "Knife you tonight", "Hey Sam, what kind of suit do you wanna be buried in?!" },
Message{"paypalservices#hotmail.com", "Urgent from paypal.com", "Dear paypal user, someone has hacked your account. Give us your password now so we change it!"},
};
viewMessages(inbox);
// Maybe call viewMessages again to see results of erase...
}
As I have commented, watch out for error checking on your input.

memory address prints aswell as string?

I'm trying to print out the contents of my array, however it also prints the memory address of each element, then prints the element.
void generateEndOfDayReport(taxiDetails taxiDataStore[], fareDetails reportArray[])
for (int i = 0; i < 14; i++)
{ cout << "Here is a list of the taxi drivers in ascending last name order: " <<
cout << taxiDataStore[i].taxiDriverSurname << endl << "And here is the money they took in over the course of today: £" << taxiDataStore[i].fareDetailsForTaxi.overAllFareDetails << endl << endl;
}![enter image description here][1]
By the look of your code, you've got a typo, it reads:
cout << some-text << cout << variable << endl << some-more-text << variable << endl << endl;
Note that you are streaming cout into cout. Is that really what you intended?