0

For some reason why I run the code now I do not get this error.
Overall looking at the code that has been posted am I going the right way? Can I put a max on my shoes object i.e.

Shoe * shoes[10];  // in shoes.h
Shoe_List shoes[10]; // in main.cpp

Because when I try this I get errors in the function and calling it:

shoes = new shoes[10]; //expression must be a modifiable value

I guess I can just remove this as I will have set the size already. And:

shoes.load();  //expression must have class type

Or should I really be using vectors? I do need to set a max size though of 10.

0

Ok right I see what you mean Moschops. So if you see the whole code posted earlier is this the right direction to be going in having two classes, Shoe and Shoe_List? Are you saying I should do this for all my functions? I might be starting to confuse myself here

0

Sorry for the late reply but thanks for the help. Not sure if I should be posting on this thread again since it is quite old? But a question about the class Shoe that was initial posted on page 1. If the variables are private in Shoe how can I display shoes? If they are private and I do:

for (int i=0; i<length; i++)
    {
        cout << shoes[i].Name << endl;
        cout << shoes[i].Number << endl;
        cout << shoes[i].ShoeSize << endl;
        cout << endl;
    }

Then these members won't be accessible..

0

Ok. I think this is short....

Shoes.h

#include <iostream>
#include <fstream>
#include <string>

#ifndef Shoes_Shoes_h
#define Shoes_Shoes_h

using namespace std;

class Shoe
{
public:

    //Constructors
    Shoe();
    Shoe(string Name_, int Number_, double ShoeSize_);

    //Destructor
    ~Shoe();

    //Getters
    string getName() const;
    double getShoeSize() const;
    int getNumber() const;

    //Setters
    void setName(const string Name_);
    void setShoeSize(const double ShoeSize_);
    void setNumber(const int Number_);

    friend ifstream &operator>>(ifstream  &fin, Shoe &S)
    { 
        fin >> S.Name >> S.Number >> S.ShoeSize;
        return fin;            
    }

    //Variables
    string Name;
    int Number;
    double ShoeSize;

};

class Shoe_List
{
public:

    //Constructor
    Shoe_List();

    //Functions
    void load();

private:

    //Database Length
    int length;

    //Pointer from Shoe object to array shoes
    Shoe * shoes;
};

#endif

Shoes.cpp

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

#include "Shoes.h"

using namespace std;

//Shoe Constructors
Shoe::Shoe()
{
    Name = "";
    Number = 0;
    ShoeSize = 0;
}

Shoe::Shoe(string Name_, int Number_, double ShoeSize_)
{
    Name = Name_;
    Number = Number_;
    ShoeSize = ShoeSize_;
}

//Shoe Destructor
Shoe::~Shoe()
{

}

//Shoe Getters
string Shoe::getName() const
{
    return Name;
}

double Shoe::getShoeSize() const
{
    return ShoeSize;
}

int Shoe::getNumber() const
{
    return Number;
}

//Shoe Setters
void Shoe::setName(const string Name_)
{
    Name = Name_;
}

void Shoe::setShoeSize(const double ShoeSize_)
{
    ShoeSize = ShoeSize_;
}

void Shoe::setNumber(const int Number_)
{
    Number = Number_;
}

//Shoe_List Constructor
Shoe_List::Shoe_List()
{
    shoes = NULL;
    int length = 0;
}

void Shoe_List::load()
{

    ifstream fin; 

    fin.open("shoe_list.txt");

    if(fin.good()) 
    {
        fin >> length;

        shoes = new Shoe[10];

        for (int i=0; i<length; i++)
        {
            fin >> shoes[i];
        }
    }

    fin.close();

} ...
0

I have been told it is good to overload the stream extraction operator to load data from a file. Would I simple use this in my class:

friend ifstream &operator>>( ifstream  &input, Class &C )
      { 
         input >> C.variable1 >> C.variable2 >> C.variable3;
         return input;            
      }

What are the advantages of overloading the stream extraction operator to read data from a file? Also I am confused what to do in main. At the moment to read in the data I have for example:

ifstream fin; 

    fin.open("filename.txt");

    if(fin.good()) 
    {

        object1 = new Class[10];

        for (int i=0; i<10; i++)
        {
            fin >> object1[i].variable1;
            fin >> object1[i].variable2;
            fin >> object1[i].variable3;
        }
    }

Do I simple use something along the lines of:

Class::read(std::ifstream& input)
{

    input >> object1;

}

Then call the function:

object1.read(filename)
0

There's no need to be so blunt or arrogant; well that is how you are coming across to me anyway. Im here to learn after all. Maybe that should have been 'What ELSE would you suggest?' I'm not worrying about best practice I'm only asking since there is no harm in learning this along the way.

0

Ok but this still gives me the following errors:

error C3867: 'Shoe_List::sortname': function call missing argument list; use '&Shoe_List::sortname' to create a pointer to member

error C3867: 'Shoe_List::sortshoesize': function call missing argument list; use '&Shoe_List::sortshoesize' to create a pointer to member

error C2664: 'strcmp' : cannot convert parameter 1 from 'const std::string' to 'const char *'

Maybe I am not understanding you correctly?

0

I have created a basic object oriented database of a list of shoes containing the shoe name, number and shoe size. I am trying to sort the list of shoes alphabetially by name and by shoe size. I have the following code:

Shoes.h:

#include <iostream>
#include <fstream>
#include <string>

#ifndef Shoes_Shoes_h
#define Shoes_Shoes_h

using namespace std;

class Shoe
{
public:

    //Constructors
    Shoe();
    Shoe(string Name_, double ShoeSize_, int Number_);

    //Destructor
    ~Shoe();

    //Getters
    string getName() const;
    double getShoeSize() const;
    int getNumber() const;

    //Setters
    void setName(const string Name_);
    void setShoeSize(const double ShoeSize_);
    void setNumber(const int Number_);

    //Variables
    string Name;
    double ShoeSize;
    int Number;

};

class Shoe_List
{
public:

    //Constructor
    Shoe_List();

    //Functions
    void load();
    void add();
    void save();
    void sort();
    int sortname(const void*, const void*);
    int sortshoesize(const void*, const void*);
    void view();

private:

    int length;
    Shoe * shoes;
};

#endif

Shoes.cpp:

#include <iostream>
#include <fstream>
#include <string>

#include "Shoes.h"

using namespace std;

//Shoe Constructors
Shoe::Shoe()
{
    Name = "";
    ShoeSize = 0;
    Number = 0;
}

Shoe::Shoe(string Name_, double ShoeSize_, int Number_)
{
    Name = Name_;
    ShoeSize = ShoeSize_;
    Number = Number_;
}

//Shoe Destructor
Shoe::~Shoe()
{

}

//Shoe Getters
string Shoe::getName() const
{
    return Name;
}

double Shoe::getShoeSize() const
{
    return ShoeSize;
}

int Shoe::getNumber() const
{
    return Number;
}

//Shoe Setters
void Shoe::setName(const string Name_)
{
    Name = Name_;
}

void Shoe::setShoeSize(const double ShoeSize_)
{
    ShoeSize = ShoeSize_;
}

void Shoe::setNumber(const int Number_)
{
    Number = Number_;
}

//Shoe_List Constructor
Shoe_List::Shoe_List()
{
    shoes = NULL;
    int length = 0;
}

void Shoe_List::load() ...
0

Didnt see that for the life of me! Thank you all for your help I have learnt a lot!
One last thing. If I am adding functions such as save would it be better code practice to pass the shoes array as const and also the length as call by value for the functions save and view since they shouldn't change for these functions? And then the opposite for functions that do want to change the shoes array and length? So:

//Functions that do not intend to change shoes and length
void Shoe_List::save(const Shoe * shoes, int length);
void Shoe_List::view(const Shoe * shoes, int length);

//Functions that do intend to change shoes and length
void Shoe_List::load(Shoe * shoes, int & length);
void Shoe_List::add(Shoe & shoes, int & length);
0

Sure:

Shoes.h:

#include <iostream>
#include <fstream>
#include <string>

#ifndef Shoes_Shoes_h
#define Shoes_Shoes_h

using namespace std;

class Shoe
{
public:

    //Constructors
    Shoe();
    Shoe(string Name_, double ShoeSize_, int Number_);

    //Destructor
    ~Shoe();

    //getters
    string getName() const;
    double getShoeSize() const;
    int getNumber() const;

    //setters
    void setName(const string Name_);
    void setShoeSize(const double ShoeSize_);
    void setNumber(const int Number_);

    string Name;
    double ShoeSize;
    int Number;

};

class Shoe_List
{
public:

    Shoe_List();

    void load();

    void view();

private:
    int length;
    Shoe * shoes;
};

#endif

Shoes.cpp:

#include <iostream>
#include <fstream>
#include <string>

#include "Shoes.h"

using namespace std;

//Shoe Constructors
Shoe::Shoe()
{
    Name = "";
    ShoeSize = 0;
    Number = 0;
}

Shoe::Shoe(string Name_, double ShoeSize_, int Number_)
{
    Name = Name_;
    ShoeSize = ShoeSize_;
    Number = Number_;
}

//Shoe Destructor
Shoe::~Shoe()
{

}

//Shoe Getters
string Shoe::getName() const
{
    return Name;
}

double Shoe::getShoeSize() const
{
    return ShoeSize;
}

int Shoe::getNumber() const
{
    return Number;
}

//Shoe Setters
void Shoe::setName(const string Name_)
{
    Name = Name_;
}

void Shoe::setShoeSize(const double ShoeSize_)
{
    ShoeSize = ShoeSize_;
}

void Shoe::setNumber(const int Number_)
{
    Number = Number_;
}

//Shoe_List Constructor
Shoe_List::Shoe_List()
{
    shoes = NULL;
    int length = 0;
}

void Shoe_List::load()
{

    fstream fin; 

    fin.open("shoe_list.txt");

    if(fin.good()) 
    {
        fin >> length;

        shoes = new Shoe[10];

        for (int i=0; i<length; i++) 
        {
            fin >> shoes[i].Name;
            fin >> shoes[i].ShoeSize;
            fin >> shoes[i].Number;
        }
    }

    fin.close();

}

void Shoe_List::view()
{

    for (int i=0; i<length; i++)
    {
        cout << shoes[i].Name << endl;
        cout << shoes[i].ShoeSize << endl;
        cout << shoes[i].Number << endl;
        cout << endl;
    } ...
0

To access the shoes would this simply be done using get. So Shoe::get();
Doesn't having these two classes also go against the idea of encapsulation?

Also putting:

shoes = new Shoe[size];

That is setting a dynamic array right? I would like a max size of 50. I tried:

shoes = Shoe[50];

but it said that it was an illegal use of this type as an expression.

That aside, as a test I set the variables in Shoe to public so I could access them. I loaded the data using (where length was declared in Shoe_List):

fstream fin; 

    fin.open("database.txt", ios::in);

    if(fin.good()) 
    {
        fin >> size;

        shoes = new Shoe[size];

        for (int i=0; i<size; i++) 
        {
            fin >> shoes[i].Name;
            fin >> shoes[i].ShoeSize;
            fin >> shoes[i].Number;
        }
    }

    fin.close();

When I then printed out the data I got the correct size (6 in this case) but only the first shoe was printed correctly and the other 5 printed as 0's :-S

0

But then how would I call the function in main.cpp because load or display are not part of shoe. I tried using:

Shoe_List[i].load(); 

but this gave the errors:

missing ';' before ']'...
'i' attribute not found

I then tried passing the Shoe object:

void load(Shoe* shoes);

Shoe_List[i].load(&shoe);

but I still get the same errors....

0

Sure;

Shoes.h:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

#ifndef Project1_Shoes_h
#define Project1_Shoes_h

class Shoes
{    
public:
    //Constructor
    Shoes();

    void Enter(Shoes&, unsigned long&);
    void Load(Shoes*, unsigned long&);  
    void View(const Shoes*, unsigned long);  

private:
    unsigned long length;
    char Name[20];  
    unsigned int Number;
    double ShoeSize;

};

#endif

Shoes.cpp

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

#include "Shoes.h"  

Shoes::Shoes()
{
   Number = 0;
   ShoeSize = 0.0;
   length = 0;
}

void Shoes::Enter(Shoes& Shoe, unsigned long& length)
{
    cout << "Enter New Shoe" << endl;
}

void Shoes::Load(Shoes* Shoe, unsigned long& length)
{

    fstream input_file;  

    input_file.open("shoe_list.txt");

    if(input_file.good())
    {
        input_file >> length;

        for (unsigned long i=0; i<length; i++)
        {
            input_file >> Shoe[i].Name;
            input_file >> Shoe[i].Number;
            input_file >> Shoe[i].ShoeSize;
        }
    }

    input_file.close();
}

void Shoes::View(const Shoes* Shoe, unsigned long length)
{
    cout << length << endl <<endl;

    for (unsigned long i=0; i<length ;i++)
    {
        cout << Shoe[i].Name << endl;
        cout << Shoe[i].Number << endl;
        cout << Shoe[i].ShoeSize << endl;
        cout << endl;
    }

}

main.cpp

#include <iostream>
#include <fstream>
#include <string>

#include "Shoes.h"

using namespace std;

int main()
{
    const int MAX = 10;
    int i =0;
    Shoes Shoe[MAX];

    char input;

    while (1) {
        // show the menu of options
        cout << endl;
        cout << "Menu" << endl;
        cout << "1. Enter" << endl;
        cout << "2. Load" << endl;
        cout << "3. View" << endl;
        cout << "4. Exit" << endl << endl;

        cout << "Enter your option: ";
        cin >> input;
        cout << endl;

        switch(input) {
            case '1':
                Shoe[i].Enter(Shoe[length]);
                break; ...
0

I put length equal to 6 as the program was printing garbage so it read in something like 345657 into length :-S

Making changes I now get some errors:

error C2228: left of '.Load' must have class/struct/union
          type is 'Shoes [50]'

and:

error C2065: 'length' : undeclared identifier

even though I have declared length in the class Shoes ...

0

Ok thanks for the help. I have simply tried reading a text file with the shoe information in but the output is garbage. I have the following files:

Shoes.h:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

#ifndef Project1_Shoes_h
#define Project1_Shoes_h

class Shoes
{    
public:
    //Constructor
    Shoes();

    void View(Shoes* Shoe);  
    void Display(Shoes* Shoe);  

private:
    unsigned long length;
    char Name[10];  
    unsigned int Number;
    double ShoeSize;

};

#endif

Shoes.cpp:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

#include "Shoes.h"  

Shoes::Shoes()
{

}

void Shoes::Load(Shoes* Shoe)
{

    fstream input_file;  

    input_file.open("shoe_list.txt");

    // load length information from file
    if(input_file.good())
    {
        input_file >> length;

        for (unsigned long i=0; i<6; i++)
        {
            input_file >> Shoe[i].Name;
            input_file >> Shoe[i].Number;
            input_file >> Shoe[i].ShoeSize;
        }
    }

    input_file.close();
}

void Shoes::View(Shoes* Shoe)
{
    cout << length << endl <<endl;

    for (unsigned long i=0; i<6 ;i++)
    {
        cout << Shoe[i].Name << endl;
        cout << Shoe[i].Number << endl;
        cout << Shoe[i].ShoeSize << endl;
        cout << endl;
    }

}

main.cpp:

#include <iostream>
#include <fstream>
#include <string>

#include "Shoes.h"

using namespace std;

//#define MAX 50

int main()
{
    Shoes Shoe[MAX];

    char input;

    while (1) {
        cout << endl;
        cout << "Menu" << endl;
        cout << "(1) Load" << endl;
        cout << "(2) View" << endl;
        cout << "(3) Exit" << endl;

        cout << "Enter your option: ";
        cin >> UserInput;
        cout << endl; 

        switch(input) {
            case '1':
                Shoe.Load(&Shoe);
                break;
            case '2':
                Shoe.View(&Shoe);
                break;
            case '3':
                return 0;
            default:
                cout << "Invalid entry" << endl << endl;
                break;
        }
    }
    return 0;
}

shoe_list.txt: ...