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)

Recommended Answers

All 7 Replies

What are the advantages of overloading the stream extraction operator to read data from a file?

Among other things:

  • It saves the user of the class a lot of trouble in customizing I/O.
  • It saves you from having to design individual access to data members.
  • It's cleaner overall.
  • It makes your code more future-proof if there are changes (ie. you don't need to change every place the class is used).

Also I am confused what to do in main.

It becomes as simple as this, regardless of how many data members you have or whether they're publicly accessible:

if(fin.good()) 
{
    object1 = new Class[10];

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

Ok thanks! The code compiles and works but I get an error with ">>" on the line:

fin >> object1[i];

It says:

Erro: No operator ">>" matches these operands

Please post a complete (short!) example that I can compile.

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();

}

Main.cpp

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

#include "Shoes.h"

using namespace std;

int main()
{
    Shoe_List shoes;

    char input;
    int i = 0;

    while (1) 
    {

        cout << endl;
        cout << "Menu" << endl;
        cout << "1. Load" << endl;
        cout << "Enter option: ";
        cin >> input;
        cout << endl;
        // act on the user's input
        switch(input) 
        {
            case '1':
                shoes.load();
                break;

            default:
                cout << "Incorrect entry" << endl << endl;
                break;
        }
    }
}

shoe_list.txt

6

Nike
8
0.6

Addidas
5
3.5

Nike
5
6

Puma
8
2

Lacoste
8
100

Umbro
14
100

Is the error reffering to line 85 in shoes.cpp? I am not seeing anything wrong with the code.

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.

Or should I really be using vectors?

Given that you seem to be having quite a bit of trouble with arrays and pointers, I'm going to go with yes, you should be using vectors.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.