Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 267
  • Last Modified:

OOP in C++ and overloaded operators << & >>

Hello

Is there anyone who can answer some questions regarding C++ OOP? What I'm, trying to achieve is that I have class client file with main function which instatiate object from class "fisrtclass":

#include "firstclass.h"

firstclass dataArray[10];

then its opens the file :

in.open(fileName);

and reads from file straight to:

in >> dataArray[count];

-------
At this point I need a hint. How can I futher manipulate data input from this file. For example I need just first three words and so on. How to create overloaded operator>> for firstclass. What I need is that if my file contain:

string1 string2 string3
string4 string5 string6
 
so my:
dataArray[1] = {"string1","string2","string3"}
dataArray[2] = {"string4","string5","string6"}


Can anyone push me forward a bit? :-) please ask me question if my scenario is unclear to you.

thank you









0
Luxana
Asked:
Luxana
3 Solutions
 
chip3dCommented:
hi, Luxana

overloaded operator for this task is quite easy:

std::istream& operator>>(std::istream &in, firstclass &c)
{
  //here you need access to your members of firstclass
  // one way is to define this function as friend in firstclass, than you cann access your members directly:
  in >> c.string1 >> c.string2 >> c.string3;
  // or you use a set function:
  std::string s1, s2, s3;
  in >> s1 >> s2 >> s3;
  c.set(s1,s2,s3);
  return in;
}
0
 
rstaveleyCommented:
Real world data is mucky and chip3d's implementation isn't great at dealing with invalid records. In my experience, std::istream& operator>> needs to be treated with kid gloves.

If you need to consider the possibility of poor input data, consider having record delimiters as well as field delimiters and keep them distinct. If you have one invalid input record, you can resync with the next, if you put the record into its own input stream, using a stringstream.

e.g. If you never have a '\n' character in your data, which not use that to delimit records?
e.g. If you never have a '|' character in your data, which not use that to delimit fields (that allows you to have spaces in your strings)?

That allows you to store serialised data in the form:

   yada|yada yada|yada|
   yada yada|yada yada|yada|
   yada|yada yada|yada yada|

You can then have something like...

std::istream& operator>>(std::istream &in, firstclass &c)
{
  // First read an input record
  std::string record;
  if (getline(in,record)) {    //  Equivalent to: getline(in,record,'\n')
     // Use a stringstream to tokenise the record - that way, if the string stream
     // has bad input, you don't set any failure flags in the in stream
     std::istringstream istr(record);
     std::string s1, s2, s3;
     if (getline(istr,s1,'|') && getline(istr,s2,'|') && getline(istr,s3,'|')) {
        c.set(s1,s2,s3);
     }
     else {
        // Life goes on??
        std::cerr << "Warning: Invalid record: " << record << '\n';
     }
  }
  return in;
}

If you can't find a suitable character for field and record delimiters, it is time to consider XML.
0
 
itsmeandnobodyelseCommented:
>>>> some questions regarding C++ OOP

rstavely showed you how to load data for *one* instance of class 'firstdata'. If I understood your request correctly, the first three text words of any line of the input file were used to set the member data of a 'firstdata' object. You should ask yourself whether that is well defined.

Some questions:

Are there some lines that have more than 3 text words? If yes, why didn't you store them?

Are there lines that have less than 3 words? What do you want to do if that happened?

Are there any 'text words' that may contain spaces? I recently read a sample where "Del Los Santos" needed to be treated as *one* name. So if your input file contains textfields rather than text words you might consider a different separator to a space character, say '|' - as rstaveley used - or ';'  Or, you need to quote the text, e. g.

    "string1" "string2" "string3"

>>>> firstclass dataArray[10];

Actually, if a main() uses an array of elements like that it isn't OOP.

You might consider a new class - a container that would encapsulate the array and has an overloaded operator>> as well:

class firstclass_container
{
     enum { MAX_DATA = 10 };
     firstclass dataArray[MAX_DATA];
public:
    ...
    friend istream operator>>(istream& is, const firstclass_container% fc)
    {
         for (int i  = 0; i < MAX_DATA; ++i)
         {
               is >> dataArray[i];
               if (is.fail())
                     break;
         }
         return is;
    }
};

Then, in main() you have

   firstclass_container  fc;
   ifstream ifs("input.txt");
   ifs >> fc;

That is better that running the array in the main() what would be still procedural.

But, you might improve it further:

class firstclass_manager
{
        firstclass_container  fc;
        string inputfile;
public:
          firstclass_manager(const string& file) : inputfile(file);
          bool loadData();
          void run();
};

Then your main turns to

int main()
{
       firstclass_manager fm("input.txt");
       if (fm.loadData())
             fm.run();
       else
             return 1;   // error return
       return 0;
}

Regards, Alex
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now