marcon33
asked on
C ++ file input looping thru sets of data
This is my first posting. I need to process the contents of a file that has about 4000
records where every 12 to 36 lines represent a discrete set of data that needs
to be fed into an object.
I have been able to open the file, fill an object but moving to the next
block of 12 to 36 lines has me scratching my head. How do I set up a loop
to do this.
If the “dealer” or “part number” changes then the block of data is done and the next object should be filled.
Implementation ( .cpp) , the data file itself appear below and the class (.h).
#pragma warning(disable:4786)
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <stdlib.h>
#include "partNo.h"
using namespace std;
int main()
{
string s1, s3, s4, s5, s6; // s1 dealer code, s3 partnumber
char delim[]=","; // comma delimter to look for
int m = 0; // index for moving thru vector
ifstream f("test.txt"); // open file
vector<string> vs; // vector to hold each string
vector<string>::iterator strit ;
while(f)
{
string s;
getline(f,s);
vs.push_back(s); // put the entire string in the vector
};
while(strit != vs.end()) // loop thru the vector parsing each line
{
PartNumber p; // part number class
string s2 = vs[m]; // using vector index assign string to string variable
int j = 0, k =0; // placement variables
int i=0; // for moving thru string
int dcnt = 0; // count delimters to parse out dealer info
do{
i = s2.find_first_of(delim, j); // find first delimiter , set i to end of string
dcnt = dcnt + 1; // increment delimiter count
// each delimiter parses out a field based on dcnt
switch(dcnt)
{
case 1 :
s3.assign(s2,j,i-j); // assign s2 with k start and i end of string , grab dealer
// cout << s3 << " " ;
p.setDealer(s3); // update dealer in part object
break; // causes exit from loop
case 2 :
s4.assign(s2,j,i-j); // grab partnumber
p.setPartNumber(s4); // update partnumber in part object
// cout << s4 << " " ;
break;
case 3 :
// s5.assign(s2,j,i-j); // date unused field
// p.set
// cout << s5 << " " ;
break;
case 4 :
s6.assign(s2,j,10); // units
//cout << s6 << endl;
// convert the string to double
p.setDmd(atof(s6.c_str())) ; // update dmd vector in part object
break;
}
j = i+1; // move the start for delim search forward
// }while(i < s2.length()); // VERIFY THIS
}while( i < s2.find_last_of(delim, 0)); // and i >= 0 ???
p.getDmd(); // prints the units of demand contents of vector
m++; // increment counter for vector
}
// code needs to be added to put each object into a container for future work
return 0;
}
/* test.txt note should stop at change
in dealer or partnumber.
A025,5-280X,01-JAN-03,1.00
A025,5-280X,01-FEB-03,2.00
A025,5-280X,01-MAR-03,3.00
A025,5-280X,01-APR-03,4.00
A025,5-280X,01-MAY-03,5.00
A025,5-280X,01-JUN-03,6.00
A025,5-280X,01-JUL-03,7.00
A025,5-280X,01-AUG-03,8.00
A025,M10130,01-JAN-03,9.00
A082,LE1000,01-JAN-03,10.0 0
A082,LE1000,01-FEB-03,12.0 0
A082,LE1000,01-MAR-03,12.0 0
*/
/// class /////
#include <iostream>
#include <string>
using namespace std;
class PartNumber
{
public :
friend ostream& operator<< (ostream& ostr, const PartNumber& obj);
setDealer( string& s) ; // address constants here and below
setPartNumber(string& s);
string getDealer() ;
void getPartNumber();
setDmd(const double& units);
void getDmd();
private :
string strDealer;
string strPartNumber;
double unitDemand;
vector<double> vdmd; // hold units of demand
vector<double>::iterator p ;
};
void PartNumber::getDmd()
{
if(!vdmd.empty())
{
p = vdmd.begin();
while(p != vdmd.end())
{
cout << *p << " " << "units stored in obj's vector" << endl ;
p++;
}
}
}
// set the unitDemand variable
PartNumber::setDmd(const double& units)
{
vdmd.push_back(units);
}
// set dealer code
PartNumber::setDealer(stri ng& s)
{
strDealer = s;
}
// set dealer code
PartNumber::setPartNumber( string& s)
{
strDealer = s;
}
// get the dealer code
string PartNumber::getDealer()
{
return strDealer;
}
// output the object
ostream& operator<< (ostream& ostr, const PartNumber& obj) // output
{
ostr << obj;
return ostr;
}
records where every 12 to 36 lines represent a discrete set of data that needs
to be fed into an object.
I have been able to open the file, fill an object but moving to the next
block of 12 to 36 lines has me scratching my head. How do I set up a loop
to do this.
If the “dealer” or “part number” changes then the block of data is done and the next object should be filled.
Implementation ( .cpp) , the data file itself appear below and the class (.h).
#pragma warning(disable:4786)
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <stdlib.h>
#include "partNo.h"
using namespace std;
int main()
{
string s1, s3, s4, s5, s6; // s1 dealer code, s3 partnumber
char delim[]=","; // comma delimter to look for
int m = 0; // index for moving thru vector
ifstream f("test.txt"); // open file
vector<string> vs; // vector to hold each string
vector<string>::iterator strit ;
while(f)
{
string s;
getline(f,s);
vs.push_back(s); // put the entire string in the vector
};
while(strit != vs.end()) // loop thru the vector parsing each line
{
PartNumber p; // part number class
string s2 = vs[m]; // using vector index assign string to string variable
int j = 0, k =0; // placement variables
int i=0; // for moving thru string
int dcnt = 0; // count delimters to parse out dealer info
do{
i = s2.find_first_of(delim, j); // find first delimiter , set i to end of string
dcnt = dcnt + 1; // increment delimiter count
// each delimiter parses out a field based on dcnt
switch(dcnt)
{
case 1 :
s3.assign(s2,j,i-j); // assign s2 with k start and i end of string , grab dealer
// cout << s3 << " " ;
p.setDealer(s3); // update dealer in part object
break; // causes exit from loop
case 2 :
s4.assign(s2,j,i-j); // grab partnumber
p.setPartNumber(s4); // update partnumber in part object
// cout << s4 << " " ;
break;
case 3 :
// s5.assign(s2,j,i-j); // date unused field
// p.set
// cout << s5 << " " ;
break;
case 4 :
s6.assign(s2,j,10); // units
//cout << s6 << endl;
// convert the string to double
p.setDmd(atof(s6.c_str()))
break;
}
j = i+1; // move the start for delim search forward
// }while(i < s2.length()); // VERIFY THIS
}while( i < s2.find_last_of(delim, 0)); // and i >= 0 ???
p.getDmd(); // prints the units of demand contents of vector
m++; // increment counter for vector
}
// code needs to be added to put each object into a container for future work
return 0;
}
/* test.txt note should stop at change
in dealer or partnumber.
A025,5-280X,01-JAN-03,1.00
A025,5-280X,01-FEB-03,2.00
A025,5-280X,01-MAR-03,3.00
A025,5-280X,01-APR-03,4.00
A025,5-280X,01-MAY-03,5.00
A025,5-280X,01-JUN-03,6.00
A025,5-280X,01-JUL-03,7.00
A025,5-280X,01-AUG-03,8.00
A025,M10130,01-JAN-03,9.00
A082,LE1000,01-JAN-03,10.0
A082,LE1000,01-FEB-03,12.0
A082,LE1000,01-MAR-03,12.0
*/
/// class /////
#include <iostream>
#include <string>
using namespace std;
class PartNumber
{
public :
friend ostream& operator<< (ostream& ostr, const PartNumber& obj);
setDealer( string& s) ; // address constants here and below
setPartNumber(string& s);
string getDealer() ;
void getPartNumber();
setDmd(const double& units);
void getDmd();
private :
string strDealer;
string strPartNumber;
double unitDemand;
vector<double> vdmd; // hold units of demand
vector<double>::iterator p ;
};
void PartNumber::getDmd()
{
if(!vdmd.empty())
{
p = vdmd.begin();
while(p != vdmd.end())
{
cout << *p << " " << "units stored in obj's vector" << endl ;
p++;
}
}
}
// set the unitDemand variable
PartNumber::setDmd(const double& units)
{
vdmd.push_back(units);
}
// set dealer code
PartNumber::setDealer(stri
{
strDealer = s;
}
// set dealer code
PartNumber::setPartNumber(
{
strDealer = s;
}
// get the dealer code
string PartNumber::getDealer()
{
return strDealer;
}
// output the object
ostream& operator<< (ostream& ostr, const PartNumber& obj) // output
{
ostr << obj;
return ostr;
}
ASKER
thanks for the thought. I can process each string held by the vector and even move thru each element of the vector. It is how to stop and start over with a new object that is the problem.
My latest thought is maybe a queue (?) could be used at the beginning , popping the strings that all have the same dealer code and part , then stopping and starting over when they change.
My latest thought is maybe a queue (?) could be used at the beginning , popping the strings that all have the same dealer code and part , then stopping and starting over when they change.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That gives me plenty to go on. Great clarity. Thanks!
strit = vs.begin();
while(++strit != vs.end()) // loop thru the vector parsing each line
{