I'm new at programming so I'm not really sure what the problem is. The errors I keep getting are in the AddTopping(string toppings). One is illegal reference to non-static member PizzaOrder::toppings . The other one is 'initializing' can not convert for " to std::string.
This is what I've got at the moment:
#include <iostream>
#include <string>
using namespace std;
class PizzaOrder
{
private:
static const int MAX_SIZE=1000;
int size;
string toppings[MAX_SIZE];
int num_toppings;
public:
static const string toppings_offered [4];
static const int DEFAULT_SIZE= 0;
static const int DEFAULT_TOPPINGS=0;
static const double topping_base_cost;
static const double base_price;
PizzaOrder ();
PizzaOrder (int size);
bool SetSize (int size);
int GetSize () {return size;}
static string AddTopping (string topping);
static int AddTopping (int n);
static double GetPrice ();
static string StringizeSize ();
static string GetToppings ();
static void DisplayPizza();
};
const double PizzaOrder :: topping_base_cost= .5;
const double PizzaOrder :: base_price= 5;
const string PizzaOrder ::toppings_offered[4]={"olives","bell peppers","onions","pepperoni"};
int main ()
{
PizzaOrder order;
char pizza_size;
int topping_choice;
short array_size = sizeof(order.toppings_offered)/sizeof(order.toppings_offered[0]);
cout << "Would you like a size [S]small , [M]medium, [L]large pizza or [Q]quit?" <<endl;
while ( pizza_size != 'Q' || pizza_size != 'q')
{
cin >> pizza_size;
if( pizza_size == 'S' || pizza_size == 's')
order.SetSize(0);
if(pizza_size == 'M' || pizza_size == 'm')
order.SetSize(1);
if(pizza_size == 'L' || pizza_size == 'l')
order.SetSize(2);
while (topping_choice !=0)
{
cout << "Current Pizza : " << order.StringizeSize () << order.GetToppings ();
cout <<"Select an item by number. (Enter 0 when done)" << endl;
for (int i=0; i< array_size-1; i++)
{
cout << (i+1) << ". " << order.toppings_offered[i]<< endl;
}
cout << "Selection?";
cin >>topping_choice;
order.AddTopping(topping_choice);
}
}
return 0;
}
PizzaOrder::PizzaOrder()
{
size=DEFAULT_SIZE;
num_toppings=DEFAULT_TOPPINGS;
}
PizzaOrder::PizzaOrder(int size)
{
if(!SetSize(size))
size=DEFAULT_SIZE;
}
bool PizzaOrder::SetSize(int size)
{
if (size != 0 || size !=1 || size !=2)
return false;
this -> size=size;
return true;
}
string PizzaOrder::AddTopping(string topping)
{
string temp_toppings[]={toppings};
short array_size = sizeof(temp_toppings)/sizeof(temp_toppings[0]);
num_toppings+1;
toppings[num_toppings];
for(int k=0; k<array_size-1; k++)
{
toppings[k]= num_toppings[k];
}
toppings[num_toppings]= topping;
}
int PizzaOrder::AddTopping(int n)
{
string temp_toppings[]={toppings};
short array_size = sizeof(temp_toppings)/sizeof(temp_toppings[0]);
num_toppings+1;
toppings[num_toppings];
for(int k=0; k<array_size-1; k++)
{
toppings[k]= num_toppings[k];
}
toppings[num_toppings]=toppings_offered[n];
}
double PizzaOrder ::GetPrice()
{
double price;
double multiplier;
if(size==0)
multiplier=1;
if(size==1)
multiplier=1.15;
if (size==2)
multiplier=1.25;
price= (base_price*multiplier)+(num_toppings*topping_base_cost);
return price;
}
string PizzaOrder::StringizeSize()
{
if(size==0)
return "small";
if(size==1)
return "medium";
if (size==2)
return "large";
}
string PizzaOrder::GetToppings()
{
string temp= "";
for(int x=0,x<num_toppings-1, x++)
temp+= "+ " + toppings[x];
return temp;
}
void PizzaOrder::DisplayPizza()
{
cout << StringizeSize ()<< GetTopping () << GetPrice ();
}
You have a bunch of static functions that shouldn't be static, including AddTopping. Read up on static.
I'm not absolutely sure which line you're getting the "initializing cannot convert from" error on (please provide complete error information, including line numbers, in future questions), but I'd wager it's that first line in the integer overload of AddTopping. I gather that you're trying to copy the contents of the current "toppings" array member (inaccessible to you because you've declared the function static -- which is probably the reason that the type information is missing in the error message) into a temp_toppings array. The line, as you've written it, is not valid C++. I suggest you Google "C++ copy array" and read the first link, which is a nice array tutorial on the augustcouncil.com Web site.
Even if you get rid of all mistakes, you have a infinite loop running with the very beginning condition in the while loop -
The intention of this loop is to break from the loop, I assume. But it never does so -
while ( pizza_size != 'Q' || pizza_size != 'q')
{
// .....
}
When pizza_size is equal to Q, with the || condition, the condition turns out to be true and an infinite loop. It should be -
pizza_size = 'Q' => false || true => true -> while loop continues
pizza_size = 'q' => true || false => true -> while loop continues
while ( (pizza_size != 'Q') && (pizza_size != 'q'))
{
// .....
}
Hope it helps at later stages.
Related
Why my program is getting these errors?
undefined reference to `PizzaOrder::toppings_offered'
undefined reference to `PizzaOrder::arraySize'
undefined reference to `PizzaOrder::base_price'
undefined reference to `PizzaOrder::MedPizBase'
undefined reference to `PizzaOrder::base_price'
undefined reference to `PizzaOrder::LargePizBase'
...
This is my program:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class PizzaOrder
{
private:
int size;
int num_toppings;
string toppings[100];
public:
static const string toppings_offered[];
static const double topping_base_cost;
static const double base_price;
static const string defaultSize;
static const double MedPizBase;
static const double LargePizBase;
static const int arraySize;
PizzaOrder();
PizzaOrder(int size);
// MUTATORS & ACCESSORS & METHODS
int GetSize() { return size; }
int GetNumToppings() { return num_toppings; }
string GetToppings();
void GetPrice();
bool SetSize(int size);
void AddTopping(string topping);
void AddTopping(int n); //int represents position in array toppings_offered[]
string StringizeSize(int size);
void DisplayPizza();
};
const string toppings_offered[] = {"1. Onions", "2. Bell Peppers",
"3. Olives", "4. Pepperoni", "5. Sausage",
"6. Mushrooms", "7. Jalapenos"};
const string defaultSize = "Small ";
const double topping_base_cost = 1;
const double base_price = 7;
const double MedPizBase = 0.15;
const double LargePizBase = 0.25;
const int arraySize = sizeof(toppings_offered)/sizeof(toppings_offered[0]);
PizzaOrder::PizzaOrder()
{
SetSize(0);
}
PizzaOrder::PizzaOrder(int size)
{
if (!SetSize(size))
SetSize(0);
}
string PizzaOrder::StringizeSize(int size)
{
string pizzaSize;
if (size == 0)
pizzaSize = "Small";
if (size == 1)
pizzaSize = "Medium";
if (size == 2)
pizzaSize = "Large";
return pizzaSize;
}
bool PizzaOrder::SetSize(int size)
{
if (size != 0 && size != 1
&& size != 2)
return false;
this->size = size;
return true;
}
void PizzaOrder::AddTopping(string topping) // totally wrong
{
for (int i = 0; i < arraySize; i++)
{
if (topping == toppings_offered[i])
{
toppings[num_toppings] = topping;
num_toppings++;
}
}
}
void PizzaOrder::AddTopping(int n) //increments n by 1 for each valid topping chosen
{
if (n > 0 && n < 7)
n++;
n = num_toppings;
}
string PizzaOrder::GetToppings()
{
string result;
for(int i = 0; i < GetNumToppings(); i++)
{
result += toppings[i];
}
return result;
}
void PizzaOrder::DisplayPizza()
{
cout << "Your pizza order: " << PizzaOrder::StringizeSize(GetSize()) << ", "
<< PizzaOrder::GetNumToppings() << ", "
<< PizzaOrder::GetToppings();
}
void PizzaOrder::GetPrice()
{
double TotalPizPrice;
double MedPizzaPrice = base_price+(base_price*MedPizBase);
double LargePizzaPrice = base_price+(base_price*LargePizBase);
double topPrice = (GetNumToppings()*topping_base_cost);
if (GetSize() == 0)
TotalPizPrice = topPrice+base_price;
if (GetSize() == 1)
TotalPizPrice = topPrice+MedPizzaPrice;
if (GetSize() == 2)
TotalPizPrice = topPrice+LargePizzaPrice;
cout << "Your pizza's total price is: $" << TotalPizPrice;
}
int main()
{
PizzaOrder pizza;
string choice;
char selection;
int topChoice;
do
{
cout << "Size of pizza (Small, Medium, Large) or Quit?\n" << endl;
getline(cin, choice);
selection = choice[0];
if (selection == 'S' || selection == 's')
pizza.SetSize(0);
if (selection == 'M' || selection == 'm')
pizza.SetSize(1);
if (selection == 'L' || selection == 'l')
pizza.SetSize(2);
do
{
cout << "Current pizza: "
<< pizza.StringizeSize(pizza.GetSize())
<< pizza.GetToppings() << "\n"
<< "Select an item by number (0 when done):\n" << endl;
for (int i = 0; i < 8; i++)
{
cout << toppings_offered[i] << "\n";
}
cout <<"\nSelection: ";
cin >> topChoice;
pizza.AddTopping(topChoice);
}
while (topChoice != 0);
}
while(selection != 'q' && selection != 'Q');
pizza.DisplayPizza();
pizza.GetPrice();
return 0;
}
The definition of static member variables is wrong, they should be:
const string PizzaOrder::defaultSize = "Small ";
~~~~~~~~~~~~
...
Otherwize they'll be just global variables.
The class BaseSearch is the base function that I'm trying to call within the derived function (ValueSearch).
The code that I have in question specifically is under ValueSearch, calling BaseSearch::Print(line, title). The compiler errors I'm getting are:
I'm uncertain if I'm using inheritance correctly.
Error 1 error C2275: 'std::string' : illegal use of this type as an expression
BaseSearch.cpp
BaseSearch::BaseSearch()
{
}
BaseSearch::~BaseSearch()
{
}
void Print(string line, string title)
{
char c2 = '_'; //set character to blank value; defines the header row
char c = '_'; //set character to blank value; defines the searched row
int numHeader = 0; //sets the value of character for the header row
int numLine = 0; //sets the value of character for the searched row
c2 = line[numLine];
while (true) //force while loop
{
c = title[numHeader]; numHeader++; //header character is set to the title array defined as the entire header string above
if (c != ',')
{
cout << c; // couts the header until it reaches a ','
}
if (c == ',' || title.size() == numHeader) // if c reaches a ',' it will print the searched row
{
cout << ": ";
while (line.size() != numLine)
{
while (c2 != ',' && line.size() != numLine)
{
cout << line[numLine];
numLine++;
if (line.size() != numLine)
c2 = line[numLine];
else
break;
}
if (line.size() != numLine)
{
numLine++;
c2 = line[numLine];
cout << "\n";
break;
}
}
}
if (title.size() == numHeader) // if c reaches a null value, it breaks until other row is found.
{
cout << endl << endl; break;
}
}
}
BaseSearch.h
#ifndef BASESEARCH_H
#define BASESEARCH_H
#include <string>
class BaseSearch
{
public:
BaseSearch();
virtual ~BaseSearch();
virtual void Print(string, string);
};
Value Search.cpp
ValueSearch::ValueSearch()
{
string input;
}
ValueSearch::~ValueSearch()
{
//dtor
}
double ValueSearch::getInput()
{
cout << endl << "Enter the name of the company you would like to search for: ";
cin >> input;
return input;
}
void ValueSearch::ValueSearchFunc(int c, int x)
{
column = c;
// cout << "Enter the name of the company you would like to search for: ";
// getline(cin, input);
string line;
ifstream fs("Stock Database.csv");
string title;
getline(fs, title);
while (!fs.eof())
{
getline(fs, line);
string companyname = ""; //start as blank, then append
string a;
int commacount = 0; //how many commas have we passed
int ChrCount = 0; //counter for which character in the line we are looking at
while (line != "\0") //while the line does not equal to null value.
{
double price;
price = 0;
a = line[ChrCount]; //convert char c to a string (a) so that we can append
ChrCount++;
if (a == ",")
{
commacount++; //increases the comma count as a encounters a comma each time.
}
else if (commacount == column && (a != "N" && a != "/" && a != "A")) //if comma count is equal to the set column, it will append the string company name.
{
while (a != ",")
{
if (a != ",")
{
companyname.append(a);
a = line[ChrCount];
ChrCount++;
}
}ChrCount--;
price = stod(companyname);
}
else if (commacount > column) // if the comma count is any value larger than the column, breaks out of loop.
{
break;
}
if (input == 0)
{
break;
}
if (x == 1){
if (price >= input && price != 0) // if the appended company name is equal to the search input entered, it will cout the entire row.
BaseSearch::Print(line, title);
}
if (x == 2)
{
if (price <= input && price != 0) // if the appended company name is equal to the search input entered, it will cout the entire row.
BaseSearch::Print(line, title);
}//end if
}
}
}
ValueSearch.h
#ifndef VALUESEARCH_H
#define VALUESEARCH_H
#include <string>
#include "BaseSearch.h"
class ValueSearch : public BaseSearch
{
public:
ValueSearch();
~ValueSearch();
double getInput();
void ValueSearchFunc(int c, int x);
void Print(string,string) {BaseSearch::Print(string,string);}
protected:
private:
double input;
int column;
};
#endif
It seems you are a beginner of C++.I will show you an example code which will compile successfully.
BaseSearc.h:
#ifndef BASESEARCH_H
#define BASESEARCH_H
#include <string>
using namespace std;
class BaseSearch
{
public:
BaseSearch();
~BaseSearch();
void Print(string, string);
};
#endif
BaseSearch.cpp:
#include "BaseSearch.h"
#include <iostream>
BaseSearch::BaseSearch()
{
}
BaseSearch::~BaseSearch()
{
}
void BaseSearch::Print(string line, string title)
{
cout << "line:" << line << endl;
cout << "title:" << title << endl;
}
ValueSearch.h:
#ifndef VALUESEARCH_H
#define VALUESEARCH_H
#include <string>
#include "BaseSearch.h"
class ValueSearch : public BaseSearch
{
public:
ValueSearch();
~ValueSearch();
double getInput();
void ValueSearchFunc(int c, int x);
protected:
private:
double input;
int column;
};
#endif
ValueSearch.cpp:
#include "ValueSearch.h"
ValueSearch::ValueSearch()
{
}
ValueSearch::~ValueSearch()
{
}
double ValueSearch::getInput()
{
return input;
}
void ValueSearch::ValueSearchFunc(int c, int x)
{
//where is 'input' from?
//if (x == 1)
//{
// if (price >= input && price != 0)
// BaseSearch::Print(line, title);
//}
//if (x == 2)
//{
// if (price <= input && price != 0)
// BaseSearch::Print(line, title);
//}//end if
}
But I've no idea what ValueSearchFunc wants to do.
There is no realization of BaseSearch constructor/destructor in code. And Print function realization should be
void BaseSearch::Print(string line, string title)
{
//code
}
I'm trying to create a program that takes a polynomial function from the user, counts the number of terms it has, creates an array large enough to store all of the terms, and then stores the terms there. The problem is that I'm not quite sure how to add a private class variable (or more specifically, a string array) AFTER the program determines how the large the function is. I need this string array to be a private class variable because I want to be able to access its contents through other class methods to do things like, for example, cout each of the function terms.
main.cpp:
#include <iostream>
#include <string>
#include "Function.h"
using namespace std;
int main()
{
Function func1;
func1.coutFuncTerms();
func1.coutFunc();
return 0;
}
Function.h:
#ifndef FUNCTION_H
#define FUNCTION_H
#include <iostream>
#include <string>
#include "Function.h"
using namespace std;
class Function
{
public:
Function();
~Function();
void removePlus(string*);
void removeWhitespace(string*);
void setFuncTerms();
void splitTerms();
void coutFuncTerms();
void coutFunc();
void coutTerms(string);
protected:
private:
string func;
int funcTerms;
};
#endif
Function.cpp:
#include <iostream>
#include <string>
#include "Function.h"
using namespace std;
// Function Constructor
//
// Stores a function inputted by the user
// Adds a null character ('\0') to the end of a string
// Erases a redundant '+' sign at the beginning of a string if there's one there
// Erases any whitespace characters in a string
// Stores the number of terms in the function
Function::Function()
{
getline(cin, func);
setFuncTerms();
//splitTerms();
}
Function::~Function()
{
}
// removePlus Function
//
// Erases a redundant '+' sign at the beginning of a string if there's one there
void Function::removePlus(string* func)
{
if(func->at(0) == '+')
{
func->erase(0, 1);
}
}
// removeWhitespace Function
//
// Erases any whitespace characters in a string
void Function::removeWhitespace(string* func)
{
for(int x = 0; unsigned(x) < func->length() - 1; x++)
{
while(func->at(x) == ' ' || func->at(x) == '\t')
{
func->erase(x, 1);
}
}
}
// setFuncLength Function
//
// Finds the number of terms in a Function object's 'func' variable
// Assigns this number to the object's 'funcLength' variable
void Function::setFuncTerms()
{
funcTerms = 0;
for(int funcTerm = 0; unsigned(funcTerm) < func.length(); funcTerm += 1)
{
bool isAPotentialTerm = false;
bool isATrueTerm = false;
if(func.at(funcTerm) == '+' || func.at(funcTerm) == '-')
{
isAPotentialTerm = true;
}
if(isAPotentialTerm == true)
{
for(int newFuncTerm = funcTerm + 1; unsigned(newFuncTerm) < func.length(); newFuncTerm += 1)
{
if(func.at(newFuncTerm) == '+' || func.at(newFuncTerm) == '-')
{
break;
}
if(func.at(newFuncTerm) != ' ' && func.at(newFuncTerm) != '\t')
{
isATrueTerm = true;
break;
}
}
}
if(isATrueTerm)
{
funcTerms++;
}
}
}
// splitTerms Function
//
// Calls the splitTerm function for each term in 'func' according to the function array 'funcArray'
void Function::splitTerms()
{
string funcArray[funcTerms];
int tempFuncLength = 0;
for(int funcTerm = 0; unsigned(funcTerm) < func.length(); funcTerm += 1)
{
bool isAPotentialTerm = false;
bool isATrueTerm = false;
if(func.at(funcTerm) == '+' || func.at(funcTerm) == '-')
{
isAPotentialTerm = true;
}
if(isAPotentialTerm == true)
{
for(int newFuncTerm = funcTerm + 1; unsigned(newFuncTerm) < func.length(); newFuncTerm += 1)
{
if(func.at(newFuncTerm) == '+' || func.at(newFuncTerm) == '-')
{
break;
}
if(func.at(newFuncTerm) != ' ' && func.at(newFuncTerm) != '\t')
{
isATrueTerm = true;
break;
}
}
}
if(isATrueTerm)
{
string temp;
for(; unsigned(funcTerm) < func.length() && func.at(funcTerm) != '+' && func.at(funcTerm) != '-'; funcTerm += 1)
{
funcArray[tempFuncLength].append(1, func.at(funcTerm));
}
tempFuncLength++;
}
}
for(int x = 0; x < funcTerms; x++)
{
cout << "Term " << x + 1 << " is: " << funcArray[x] << endl;
}
}
void Function::coutFuncTerms()
{
cout << "Terms: " << funcTerms << endl;
}
void Function::coutFunc()
{
cout << "Function: " << func << endl;
}
void Function::coutTerms(string funcArrayTerm)
{
/*for(int x = 0; x < funcLength; x++)
{
cout << "Term " << x << " is: " << funcArray[x] << endl;
}*/
//cout << funcArray[0] << endl;
}
I highly recommend you change your design.
A function is a container of terms. So let's define a term:
A term minimally has a coefficient and an exponent:
struct Fundamental_Term
{
double coefficient;
int exponent;
};
If your function is only in terms of one variable, all you need is the Fundamental_Term. Otherwise, you need to have the base variable name:
struct Term_With_Base
: public Fundamental_Term
{
std::string variable_name;
};
Note: if you can't use inheritance, copy the member variables of Fundamental_Term into Term_With_Base.
Remember a function is a collection or container of terms. Assuming a function with multiple bases, we can declare:
struct Function
{
std::vector<Term_With_Base> terms;
};
Evaluation of Terms
To evaluate a function, f(x), all terms must be evaluated and their results summed.
This decomposes into two requirements: 1) Terms must have an evaluation method; 2) The function class must have an evaluation method that sums the terms.
So, we add an evaluation function to the base class:
struct Fundamental_Term
{
double coefficient;
int exponent;
double evaluate(double value)
{
return coefficient * pow(value, exponent);
}
};
struct Function
{
std::vector<Term_With_Base> terms;
double evauate(double value)
{
const unsigned int quantity = terms.size();
double result = 0.0;
for (unsigned int i = 0; i < quantity; ++i)
{
result = result + terms[i].evaluate(value);
}
return result;
}
};
When creating a function from a string, a preference is to create a constructor of Fundamental_Term that takes a string parameter. The term object should read its coefficient, variable name and exponent, not the Function container.
For more examples, search StackOverflow for "c++ parse term evaluation".
Edit 1: Inserting terms
One method to insert terms, is to have a method in the term data structure that loads a term from a string:
bool
Fundamental_Term ::
load_from string(const std::string& input,
unsigned int & start_position)
{
bool term_is_valid = false;
// Parse the string and load appropriate fields.
// Set the start position to the first position after the valid term.
// Set term_is_valid to true if the term has valid syntax.
return term_is_valid;
}
The Function object would have a member to load terms from a string.
bool
Function ::
load_terms_from_string(const std::string& input)
{
Term_With_Base term;
unsigned int position_in_string = 0;
bool term_is_valid = true;
while (term_is_valid && (position_in_string < input.size()))
{
term_is_valid = term.load_from_string(input, position_in_string);
if (term_is_valid)
{
terms.push_back(term);
}
}
}
The std::vector used to contain the terms will expand as necessary with each additional term that is parsed. The loop will terminate when the string is parsed or there is an invalid term.
I have included both my definition of the Question class and its implementation, the first is a header file and the second a cpp file.
I put comments in to show where the problem is. For some reason under the constructor I can cout the questionText just fine but when I try to do this under the getQuestionText function it just outputs an empty string? Any help would be most appreciated!! Thanks!
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#ifndef QUESTION_H
#define QUESTION_H
class Question{
public:
Question(int thePointValue, int theChapterNumber, \
string theQuestionText);
int getPointValue() const;
int getChapterNumber() const;
string getQuestionText() const;
virtual void writeQuestion(ostream& outfile) const;
virtual void writeKey(ostream& outfile) const;
private:
int pointValue;
int chapterNumber;
string questionText;
void writePointValue(ostream& outfile) const;
};
#endif
#include "Question.h"
Question::Question(int thePointValue, int theChapterNumber, \
string theQuestionText)
{
pointValue = thePointValue;
chapterNumber = theChapterNumber;
questionText = theQuestionText;
//HERE THIS WORKS PERFECTLY
cout << questionText << endl;
}
int Question::getPointValue() const
{
return pointValue;
}
int Question::getChapterNumber() const
{
return chapterNumber;
}
string Question::getQuestionText() const
{
//THIS IS THE PROBLEM. HERE IT OUPUTS AN EMPTY STRING NO MATTER WHAT!
cout << questionText << endl;
return questionText;
}
void Question::writeQuestion(ostream& outfile) const
{
writePointValue(outfile);
outfile << questionText << endl;
}
void Question::writeKey(ostream& outfile) const
{
writePointValue(outfile);
outfile << endl;
}
void Question::writePointValue(ostream& outfile) const
{
string pt_noun;
if (pointValue == 1)
pt_noun = "point";
else
pt_noun = "points";
outfile << "(" << pointValue << " " << pt_noun << ") ";
}
vector<Question *> QuestionsList(string filename, int min, int max)
{
vector<Question *> QuestionList;
string line;
vector<string> text;
ifstream in_file;
in_file.open(filename.c_str());
while (getline(in_file, line))
{
text.push_back(line);
}
string type;
for(int i = 0; i < text.size(); i ++)
{
int num = text[i].find('#');
type = text[i].substr(0, num);
if (type == "multiple")
{
MultipleChoiceQuestion myq = matchup(text[i]);
MultipleChoiceQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "short")
{
ShortAnswerQuestion myq = SAmatchup(text[i]);
ShortAnswerQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "long")
{
LongAnswerQuestion myq = LAmatchup(text[i]);
LongAnswerQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "code")
{
CodeQuestion myq = CODEmatchup(text[i]);
CodeQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
cout << QuestionList[QuestionList.size()-1]->getQuestionText() << endl;
}
for (int i = 0; i < QuestionList.size(); i ++)
{
int numm = QuestionList.size();
cout << QuestionList[numm-1]->getQuestionText() << endl;
}
return QuestionList;
}
then when i call this in main the code breaks
vector<Question *> list = QuestionsList(pool_filename, min_chapter, max_chapter);
cout << list[0]->getQuestionText() << endl;
You are declaring, multiple times in your code, local objects and storing their pointer into the QuestionList vector (returned by the function) which, at the end of the function block, will contains dangling pointers.
MultipleChoiceQuestion myq = matchup(text[i]); // < local object
MultipleChoiceQuestion* myptr = &myq; // < pointer to local object
QuestionList.push_back(myptr); // < push back into vector
At this point you can either use dynamic memory allocation (I suggest you not to do that unless you are absolutely forced, and even in that case use one of the smart pointers provided by the standard library) or store the objects directly inside the vector.
This question already has answers here:
Calling a function in main
(4 answers)
Closed 4 years ago.
Okay, I think I fixed most of this, but it doesn't like me passing the constants I think. Any help would be greatly appreciated, thank you.
also, with the !inputFile part, I'm not sure how to pull off a return (EXIT_FAILURE) like my teacher suggested..
Also, as to your suggestion with only using one part of the array, would that still allow me to use the whole thing in the function?
The program is supposed to take a file like this:
ex:
NOT 11010001
and it's supposed to read the command as a string, read the binary in as an array, then perform the command on the binary.
The code here is only main function, just don't want to send a wall of it all at once, if this looks okay, then I will happily add the rest. Also, the void Operate () function pretty much calls all of the other functions in one way or another... I'm not sure if that's what's causing it or what. The print table only cout's a table to put all of the info on.
and they headers are wonky for me on here, so just assume those are right.
/* ========================================================================== */
/* Prototypes */
int Power (int, int);
int ReadFile (ifstream inputFile);
void Operate (const int, ifstream&, string, int, int, int);
void CommandNot (const int, int, int);
void CommandAnd (const int, int, int, int);
void CommandOr (const int, int, int, int);
int CommandConvert (const int, int, int);
void CommandLshift (const int, int, int, int);
void PrintTable ();
void PrintOperand (const int &, int);
int main ()
{
//Constants
const int BIT_SIZE = 8;
//Variables
string fileName = "binaryData.txt";
int operandOne [BIT_SIZE];
int operandTwo [BIT_SIZE];
int operandResult [BIT_SIZE];
ifstream inputFile;
PrintTable ();
Operate (BIT_SIZE, inputFile, fileName, operandOne[BIT_SIZE], operandTwo[BIT_SIZE], operandResult[BIT_SIZE]);
return 0;
}
void PrintTable ()
{
cout << "=================================================" << endl;
cout << "= Eight Bit Binary Number Manipulator =" << endl;
cout << "=================================================" << endl << endl;
cout << setw(14) << "COMMAND" << "Operand #1" << "Operand #2" << "Shift" << "Result" << endl;
cout << "----------------------------------------------------------------------" << endl;
}
void Operate (const int BIT_SIZE, ifstream& inputFile, string fileName, int operandOne[], int operandTwo[], int operandResult[])
{
//Variables
int count, shift;
char myChar;
string command;
const int SIZE = BIT_SIZE; //rename constant
inputFile.open (fileName);
if ( !inputFile ) //Check if file opened sucessfully
{
cout << "Error: Data file could not be opened" << endl;
}
while (inputFile) //Read file, and apply commands
{
inputFile >> command;
cout << command << endl;
for ( count = 0; count < SIZE; count++ )
{
inputFile >> myChar;
operandOne[count] = myChar - '0';
}
if (command == "NOT")
{
CommandNot (BIT_SIZE, operandOne[BIT_SIZE], operandResult[BIT_SIZE]);
PrintOperand (BIT_SIZE, operandResult[BIT_SIZE]);
}
else if (command == "AND")
{
count = 0;
for ( count = 0; count < SIZE; count++ )
{
inputFile >> myChar;
operandTwo[count] = myChar - '0';
}
CommandAnd (BIT_SIZE, operandOne[BIT_SIZE], operandTwo[BIT_SIZE], operandResult[BIT_SIZE]);
PrintOperand (BIT_SIZE, operandResult[BIT_SIZE]);
}
else if (command == "OR")
{
count = 0;
for ( count = 0; count < SIZE; count++ )
{
inputFile >> myChar;
operandTwo[count] = myChar - '0';
}
CommandOr (BIT_SIZE, operandOne[BIT_SIZE], operandTwo[BIT_SIZE], operandResult[BIT_SIZE]);
PrintOperand (BIT_SIZE, operandResult[BIT_SIZE]);
}
else if (command == "CONVERT")
{
CommandConvert (BIT_SIZE, operandOne[BIT_SIZE], operandResult[BIT_SIZE]);
PrintOperand (BIT_SIZE, operandResult[BIT_SIZE]);
}
else if (command == "LSHIFT")
{
inputFile >> shift;
CommandLshift (BIT_SIZE, operandOne[BIT_SIZE], operandResult[BIT_SIZE], shift);
PrintOperand (BIT_SIZE, operandResult[BIT_SIZE]);
}
else
{
command = "INVALID";
PrintOperand (BIT_SIZE, operandOne[BIT_SIZE]);
cout << "--- ERROR! Invalid Command ---";
}
}
inputFile.clear();
inputFile.close();
return ;
}
void CommandNot (const int BIT_SIZE, int operandOne[], int operandResult[])
{
int count;
const int SIZE = BIT_SIZE;
for ( count = 0; count < SIZE; count++ )
{
if (operandOne[count] == 0)
{
operandResult[count] = 1;
}
else
{
operandResult[count] = 0;
}
}
}
void CommandAnd (const int BIT_SIZE, int operandOne[], int operandTwo[], int operandResult[])
{
int count;
const int SIZE = BIT_SIZE;
for ( count = 0; count < SIZE; count++ )
{
if ((operandOne[count] == 1) && (operandTwo[count] == 1))
{
operandResult[count] = 1;
}
else
{
operandResult[count] = 0;
}
}
}
void CommandOr (const int BIT_SIZE, int operandOne[], int operandTwo[], int operandResult[])
{
int count;
const int SIZE = BIT_SIZE;
for ( count = 0; count < SIZE; count++ )
{
if ((operandOne[count] == 0) && (operandTwo[count] == 0))
{
operandResult[count] = 0;
}
else
{
operandResult[count] = 1;
}
}
}
int CommandConvert (const int BIT_SIZE, int operandOne[])
{
int count;
const int SIZE = BIT_SIZE;
int baseTenResult = 0;
int place;
for ( count = 0; count < SIZE; count++ )
{
place = SIZE - (count + 1);
if (operandOne[count] == 1)
{
baseTenResult = baseTenResult + Power (2, place);
}
else
{
continue;
}
}
return baseTenResult;
}
void CommandLshift (const int BIT_SIZE, int operandOne[], int operandResult[], int shift)
{
int count;
const int SIZE = BIT_SIZE;
int shiftStart = SIZE - shift;
for ( count = 0; count < SIZE-shift; count++ )
{
operandResult[count] = operandOne[count + shift];
}
for ( count = SIZE - shift; count < SIZE; count++ )
{
operandResult[count] = 0;
}
}
int Power (int base, int power)
{
int count;
int result = 1;
for ( count = 0; count < power; count++ )
{
result = result * base;
}
return result;
}
void PrintOperand (const int BIT_SIZE, int operandResult[])
{
int count;
const int SIZE = BIT_SIZE;
for ( count = 0; count < SIZE; count++ )
{
cout << operandResult[count];
}
}
You need to call the functions from main. You can't do this by sort-of redeclaring them:
void PrintTable();
void Operate (const int BIT_SIZE, ifstream& inputFile, string fileName, int operandOne[], int operandTwo[], int operandResult[]);
Instead, you need to call them:
PrintTable();
Operate(BITSIZE,inputFile,fileName,operandOne,operandTwo,operandResult);
Note, however that there is another problem: Operate requires three integer arguments at the end, but you seem to try to use integer arrays as arguments. You'll need to select one element of each array and submit only that as argument.
(EDIT) A few things have changed in your question, and I don't understand enough to tell what the best overall structure for your data and functions should be, but if you are dealing with integer arrays and you'd like to pass an entire array to a function, you can do it in this way (I've simplified it to a function that takes only one array of integers. Of course you can have more than one function argument):
#include <iostream>
const int SIZE = 3;
/* This is a simpified version of 'operate'. It
takes one argument, which is an array of integers. */
void operate(int a[])
{
/* The only thing I do is to iterate through
all elements of the array and print them. */
int i = 0;
while (i < SIZE) {
std::cout << a[i] << std::endl;
++i;
}
/* IMPORTANT: The length of the array is defined by a
global constant SIZE. Alternatively, you can pass
along the size of the array as a separate argument
to the function. */
}
int main()
{
/* Main program. Here is our array: */
int my_array[SIZE] = { 1,2,3 };
/* And here we call our function: */
operate(my_array);
return 0;
}
However, all of this is a bit complicated and not really as conventient as you could have it in C++ (as opposed to C). In all likelihood, you'll be much better of not using arrays at all, and replacing them with std::vector. Best check on cppreference for examples of how to use it (also click on some of the member functions, such as the constructor and push_back to get specific code examples.)