By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,636 Members | 1,814 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,636 IT Pros & Developers. It's quick & easy.

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

jwwicks
P: 19
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...
Expand|Select|Wrap|Line Numbers
  1. struct product {
  2.     string id;
  3.     string description;
  4.     int quantity;
  5.     double wholesale;
  6.     double retail;
  7.     Date* date_added;
  8. };
  9.  
Got a vector of products and a file for the data...

Expand|Select|Wrap|Line Numbers
  1. vector<product> Inventory;
  2. ifstream inFile; //Input data file
  3. ofstream outFile; //Output report file
  4.  
Saved all the products to a tab delimited file, one product to each line using for_each...

Expand|Select|Wrap|Line Numbers
  1.  
  2. for_each(Inventory.begin(), Inventory.end(), save_product(&outFile));
  3.  
  4. class save_product:public std::unary_function<product, bool>
  5. {
  6. private:
  7.     ostream* m_os;
  8. public:
  9.     save_product( ostream* os ){ m_os = os; }
  10.     bool operator()( const product& element )
  11.     {
  12.         bool ret_val = false;
  13.         // save element in tab delimited format
  14.         *m_os << element.id.c_str() 
  15.             << "\t" << element.description.c_str() 
  16.             << "\t" << element.quantity 
  17.             << "\t" << element.wholesale 
  18.             << "\t" << element.retail 
  19.             << "\t" << element.date_added->get(2) // write date in month/day/year format
  20.             << "/" << element.date_added->get(1) 
  21.             << "/" << element.date_added->get(3) 
  22.             << "\r\n";
  23.         if(m_os)
  24.             ret_val = true;
  25.         return ret_val;
  26.     }
  27. };
  28.  
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...

Expand|Select|Wrap|Line Numbers
  1.  
  2. // Copy doesn't quite do what I want with data...
  3. copy( istream::iterator<T>(inFile), istream::iterator<T>(), back_inserter(Inventory) );
  4.  
  5. class load_product:public std::unary_function<product, bool>
  6. {
  7. private:
  8.     istream* m_is;
  9. public:
  10.     load_product( istream* is ){ m_is = is; }
  11.     bool operator()( product& element )
  12.     {
  13.         bool ret_val = false;
  14.         char buffer[maxStringSize];
  15.         stringstream ioConv;
  16.         unsigned int fieldCnt = 0;
  17.  
  18.         while(m_is && fieldCnt < REC_FIELD_COUNT )
  19.         {
  20.             m_is->getline(buffer,(streamsize)maxStringSize, '\t');
  21.             if(m_is)
  22.             {
  23.                 switch( fieldCnt )
  24.                 {
  25.                     case 0: element.id = buffer; break;
  26.                     case 1: element.description = buffer; break;
  27.                     case 2: ioConv >> buffer; ioConv << element.quantity; break;
  28.                     case 3: ioConv >> buffer; ioConv << element.retail; break;
  29.                     case 4: ioConv >> buffer; ioConv << element.wholesale; break;
  30.                     default:
  31.                         element.date_added->set(buffer, "/");
  32.                         break;
  33.                 }
  34.             }
  35.             fieldCnt++;
  36.             if( fieldCnt == REC_FIELD_COUNT && m_is ) ret_val = true;
  37.         }
  38.  
  39.         return ret_val;
  40.     }
  41. };
  42.  
  43.  
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
Oct 19 '07 #1
Share this Question
Share on Google+
1 Reply


jwwicks
P: 19
Hello All,

Expand|Select|Wrap|Line Numbers
  1.  
  2. // Copy doesn't quite do what I want with data...
  3. copy( istream::iterator<T>(inFile), istream::iterator<T>(), back_inserter(Inventory) );
  4.  
  5. class load_product:public std::unary_function<product, bool>
  6. {
  7. private:
  8. istream* m_is;
  9. public:
  10. load_product( istream* is ){ m_is = is; }
  11. bool operator()( product& element )
  12. {
  13. bool ret_val = false;
  14. char buffer[maxStringSize];
  15. stringstream ioConv;
  16. unsigned int fieldCnt = 0;
  17.  
  18. while(m_is && fieldCnt < REC_FIELD_COUNT )
  19. {
  20. m_is->getline(buffer,(streamsize)maxStringSize, '\t');
  21. if(m_is)
  22. {
  23. switch( fieldCnt )
  24. {
  25. case 0: element.id = buffer; break;
  26. case 1: element.description = buffer; break;
  27. case 2: ioConv >> buffer; ioConv << element.quantity; break;
  28. case 3: ioConv >> buffer; ioConv << element.retail; break;
  29. case 4: ioConv >> buffer; ioConv << element.wholesale; break;
  30. default:
  31. element.date_added->set(buffer, "/");
  32. break;
  33. }
  34. }
  35. fieldCnt++;
  36. if( fieldCnt == REC_FIELD_COUNT && m_is ) ret_val = true;
  37. }
  38.  
  39. return ret_val;
  40. }
  41. };
  42.  
  43.  
Thanks for any guidance...
John
I think I may have found the answer on another thread...
http://www.thescripts.com/forum/thread436124.html

It involves the post about a Proxy for the istream_iterator...

John
Oct 19 '07 #2

Post your reply

Sign in to post your reply or Sign up for a free account.