0

So right now I have a tab-delimited file called "customers.txt" where each customer database entry has the following format:

id<tab>name<tab>address<tab>city<tab>postcode<tab>purchaseDate<tab>amountowed

A few sample entries looks like this:

C0001   George I. Bullock   1295 Donec St.  Limena  9545    14/07/13    3548.17
C0002   Kyla M. Byrd    Ap #505-6018 Adipiscing Ave Camporotondo di Fiastrone   5773    05/06/14    6934.61
C0003   Moses J. Decker 533-2825 Turpis Rd. Carnoustie  4473    27/01/14    6801.02

I want to overload the >> operator in my Customer class file so that it correctly reads all the relevant fields, instantiates a Customer object from those fields, and then stores the newly-created Customer object inside a Customer vector. But I have no idea how to go about it. This is what I've done so far:

//main.cpp:

vector <Customer> cList;
ifstream cDbase("datafiles/customers.txt");

if (!cDbase)
{
    cerr << "Customers.txt could not be read." << endl;
    exit(1);
}

if (cDbase.good())
{
    while (!cDbase.eof())
    {
        /*
           I HAVE NO IDEA WHAT TO PUT HERE
        */
        Customer newCust = Customer(in);
        cList.push_back(newCust);
    }
    cDbase.close();
}

.

//Customer.h
private:
        std::string custID;
        std::string custName;
        std::string custAddress;
        std::string custCity;
        int custPCode;
        Date purchaseDate;
        double amountOwed;
public: 
        friend std::istream& operator>> (std::istream &in, Customer &cust);

.

//Customer.cpp:

istream& operator>> (istream &in, Customer &cust)
{
    in >> cust.custID;
    in >> cust.custName;
    in >> cust.custAddress;
    in >> cust.custCity;
    in >> cust.custPCode;
    in >> cust.amountOwed;
    return in;
}

Like I said, I have no idea what I'm doing, so any help would be much appreciated.

Another issue is the Date field. How do I read each part of the Date listed in the text file and convert it into a form where I can call my Date constructor? For example:

convert:

14/07/13

to:

Date(14,7,13)
user2742003
  • 93
  • 1
  • 4
  • I had written an answer to a similar question a couple of months ago: http://stackoverflow.com/questions/17001050/writing-a-class-object-into-a-file-using-fstream-and-then-read-it/17001490#17001490 – Manu343726 Oct 10 '13 at 11:12
  • You should also create and check a [`sentry`](http://en.cppreference.com/w/cpp/io/basic_istream/sentry#Example) object before attempting to read. This is almost always forgotten, and I was only taught this recently myself. – BoBTFish Oct 10 '13 at 11:13
  • possible duplicate of [Operator overloading](http://stackoverflow.com/questions/4421706/operator-overloading) – Manu343726 Oct 10 '13 at 11:15
  • Guys, I understand the basic concepts of operator overloading. What i DONT understand is how to separate tab-delimited fields from one another and read them correctly. Like for example, with the Date field, how do I read each part of the date (day, month, year) correctly? How do I ignore the slash ('/') between each part of the date? – user2742003 Oct 10 '13 at 11:20
  • I read through that whole link you gave me, and not one part explained how to deal with tab-delimited fields. – user2742003 Oct 10 '13 at 11:21
  • Tabs will be treated as whitespace and ignored in the same way as spaces. To read the date, you could for instance read an `int`, then `peek` to see if the next character is a `/`, if so [`ignore`]()http://en.cppreference.com/w/cpp/io/basic_istream/ignore) it, or read a single `char`, then read the next `int`, ... – BoBTFish Oct 10 '13 at 11:41
  • 1
    I've not tried it yet, but I would harbor an educated guess [`std::getline()`](http://en.cppreference.com/w/cpp/io/basic_istream/getline), with the third optional argument (the delimiter) of `'\t'` (which it tossed out) would work. Rather than using a bunch of overloaded extraction operators to read your fields, perhaps use that instead. To do individual line-processing, first use `getline` to read a full line buffer, then shove that into an `istringstream` and read the singular fields using `std::getline(iss, field, '\t')`. Fields that need even further breakup are your final task. – WhozCraig Oct 10 '13 at 11:42
  • @BoBTFish Creating a `sentry` object isn't required if you only use formatted input functions (which themselves will create one). The example you linked to also uses the unformatted input function `read`. – dyp Oct 10 '13 at 11:48
  • Sorry, my last comment had the wrong getline linked. [Try this link](http://en.cppreference.com/w/cpp/string/basic_string/getline). Again. sorry. – WhozCraig Oct 10 '13 at 11:49
  • Since tabs are treated as whitespace and ignored in the same way as spaces, how do I prevent it from ignoring the spaces between the first name, middle name, and last name, and instead read it as one field altogether? For example, "George I. Bullock" will get read as three separate fields "George, "I.", and "Bullock". How do I stop this from happening? – user2742003 Oct 10 '13 at 11:51
  • @user2742003: Don't ask us. How would you do so manually? But please, one question per question. You don't have to pay StackOverflow per question. – MSalters Oct 10 '13 at 11:59
  • @user2742003 Sorry, but you said the fields were tab-delimited. Using the method I described a few comments ago, what you're now-describing isn't an issue. If you want granular control, *don't use the formatted extraction operators*. – WhozCraig Oct 10 '13 at 14:46

0 Answers0