Reading/Writing Vector of Structs to/from Tab Delimited File

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jwwicks
    New Member
    • Oct 2007
    • 19

    Reading/Writing Vector of Structs to/from Tab Delimited File

    Hello All,

    This is a student assignment. So I don't want the complete answer just a hint or maybe a bumb on the head cause I'm doing it the wrong way. Assume I haven't done anything braindead like not include a header etc... I can post the whole code if you like/need it but I'm trying to spare the forum :)

    Got a product structure...
    [code="cpp"]
    struct product {
    string id;
    string description;
    int quantity;
    double wholesale;
    double retail;
    Date* date_added;
    };
    [/code]

    Got a vector of products and a file for the data...

    [code="cpp"]
    vector<product> Inventory;
    ifstream inFile; //Input data file
    ofstream outFile; //Output report file
    [/code]

    Saved all the products to a tab delimited file, one product to each line using for_each...

    [code="cpp"]

    for_each(Invent ory.begin(), Inventory.end() , save_product(&o utFile));

    class save_product:pu blic std::unary_func tion<product, bool>
    {
    private:
    ostream* m_os;
    public:
    save_product( ostream* os ){ m_os = os; }
    bool operator()( const product& element )
    {
    bool ret_val = false;
    // save element in tab delimited format
    *m_os << element.id.c_st r()
    << "\t" << element.descrip tion.c_str()
    << "\t" << element.quantit y
    << "\t" << element.wholesa le
    << "\t" << element.retail
    << "\t" << element.date_ad ded->get(2) // write date in month/day/year format
    << "/" << element.date_ad ded->get(1)
    << "/" << element.date_ad ded->get(3)
    << "\r\n";
    if(m_os)
    ret_val = true;
    return ret_val;
    }
    };
    [/code]

    No problem so far. The file is as I want it. But getting the data back into the vector is causing me some problems. I've seen the use of the copy algorithm for copying from a fstream to a vector but I need to tell the iterator to use tabs to delimit the text.... I wrote a functor load_product but what algorithm could I use to read the file in with...

    [code="cpp"]

    // Copy doesn't quite do what I want with data...
    copy( istream::iterat or<T>(inFile), istream::iterat or<T>(), back_inserter(I nventory) );

    class load_product:pu blic std::unary_func tion<product, bool>
    {
    private:
    istream* m_is;
    public:
    load_product( istream* is ){ m_is = is; }
    bool operator()( product& element )
    {
    bool ret_val = false;
    char buffer[maxStringSize];
    stringstream ioConv;
    unsigned int fieldCnt = 0;

    while(m_is && fieldCnt < REC_FIELD_COUNT )
    {
    m_is->getline(buffer ,(streamsize)ma xStringSize, '\t');
    if(m_is)
    {
    switch( fieldCnt )
    {
    case 0: element.id = buffer; break;
    case 1: element.descrip tion = buffer; break;
    case 2: ioConv >> buffer; ioConv << element.quantit y; break;
    case 3: ioConv >> buffer; ioConv << element.retail; break;
    case 4: ioConv >> buffer; ioConv << element.wholesa le; break;
    default:
    element.date_ad ded->set(buffer, "/");
    break;
    }
    }
    fieldCnt++;
    if( fieldCnt == REC_FIELD_COUNT && m_is ) ret_val = true;
    }

    return ret_val;
    }
    };

    [/code]

    I can do this manually with a while sure but I was hoping for a more elegant/STL way of doing it...

    Thanks for any guidance...
    John
  • jwwicks
    New Member
    • Oct 2007
    • 19

    #2
    Originally posted by jwwicks
    Hello All,

    [code="cpp"]

    // Copy doesn't quite do what I want with data...
    copy( istream::iterat or<T>(inFile), istream::iterat or<T>(), back_inserter(I nventory) );

    class load_product:pu blic std::unary_func tion<product, bool>
    {
    private:
    istream* m_is;
    public:
    load_product( istream* is ){ m_is = is; }
    bool operator()( product& element )
    {
    bool ret_val = false;
    char buffer[maxStringSize];
    stringstream ioConv;
    unsigned int fieldCnt = 0;

    while(m_is && fieldCnt < REC_FIELD_COUNT )
    {
    m_is->getline(buffer ,(streamsize)ma xStringSize, '\t');
    if(m_is)
    {
    switch( fieldCnt )
    {
    case 0: element.id = buffer; break;
    case 1: element.descrip tion = buffer; break;
    case 2: ioConv >> buffer; ioConv << element.quantit y; break;
    case 3: ioConv >> buffer; ioConv << element.retail; break;
    case 4: ioConv >> buffer; ioConv << element.wholesa le; break;
    default:
    element.date_ad ded->set(buffer, "/");
    break;
    }
    }
    fieldCnt++;
    if( fieldCnt == REC_FIELD_COUNT && m_is ) ret_val = true;
    }

    return ret_val;
    }
    };

    [/code]

    Thanks for any guidance...
    John
    I think I may have found the answer on another thread...


    It involves the post about a Proxy for the istream_iterato r...

    John

    Comment

    Working...