Reputation: 2278
guys, I have a text "sales.txt" file which contains (id, lastname, quarter, sales) in the following format.
123 smith 1 333.20
221 doe 1 345.50
342 johnson 1 774.50
123 smith 2 333.20
221 doe 2 555.50
342 johnson 2 25.50
123 smith 3 254.20
221 doe 3 652.50
342 johnson 3 32.50
123 smith 4 354.20
221 doe 4 51.50
342 johnson 4 1000.50
I'm trying to put the file into a struct for output to another text file, but so far I'm having problem with extracting the "id" and lastname. here's a portion of the code. The second method is to extract the sale by quarter and put it into array, but is not working, if someone could give me a hand with both methods
thanks
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct employees { int id; string lname; double qtrSale[4]; double tsale; };
void getIdName(employees list[], ifstream& infile, int num);
int main()
{
ifstream infile;
string file("file1.txt");
infile.open(file);
employees list[lsize];
getIdName(list, infile, lsize);
/*getData(list, file, lsize);*/
for(int i = 0; i < lsize; i++)//checking struct
{
cout << list[i].id << " " << list[i].lname << endl;
}
}
void getIdName(employees list[], ifstream& infile, int lsize)
{
int id;
string lname;
double sale, temp;
for(int i = 0; i < lsize; i++)
{
infile >> list[i].id >> list[i].lname >> temp >> sale;
/*for(int j = 1; j <= 4; j++)
{
list[i].qtrSale[j] = 0.0;
}*/
}
}
void getData(employees list[], string file, int lsize)
{
int id, qtr;
double amount;
ifstream infile(file);
while(infile.good())
{
for(int j = 0; j < lsize; j++)
{
infile >> id;
for(int i = 1; i <= 4; i++)
{
infile >> qtr >> amount;
if(list[j].id == id && qtr == 1) { list[j].qtrSale[i] = amount; }
if(list[j].id == id && qtr == 2) { list[j].qtrSale[i] = amount; }
if(list[j].id == id && qtr == 3) { list[j].qtrSale[i] = amount; }
if(list[j].id == id && qtr == 4) { list[j].qtrSale[i] = amount; }
}
}
}
}
Upvotes: 1
Views: 4638
Reputation: 1749
if you do not mind using boost.spirit. here's how it could be done(tested with vc++2010):
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
// step 1, define your struct
struct employee
{
int id;
std::string lname;
int qtrSale;
double tsale;
};
// step 2, adapt it
BOOST_FUSION_ADAPT_STRUCT(
employee,
(int, id)
(std::string, lname)
(int, qtrSale)
(double, tsale)
)
// step 3, parse it
void parse_file()
{
using namespace boost::spirit;
// open file, disable skipping of whitespace
std::ifstream in("sales.txt");
in.unsetf(std::ios::skipws);
std::vector<employee> ve;
qi::phrase_parse
(
// parse from
istream_iterator(in),
// parse to
istream_iterator(),
// reads: an int followed by a ascii string, then by a double and finally by a double, repeatedly at least once.
+(qi::int_ >> +qi::alpha >> qi::int_ >> qi::double_),
// skip all spaces
qi::ascii::space,
// save results to ve
ve
);
// print the results out
for(int i = 0; i< ve.size(); i++)
{
std::cout
<< ve[i].id << " "
<< ve[i].lname << " "
<< ve[i].qtrSale << " "
<< ve[i].tsale << std::endl;
}
}
int main()
{
parse_file();
}
Upvotes: 1
Reputation: 194
You can use the sscanf function to parse the data. Loop through the file and grab one line at a time then parse the line as follows;
`
char line []="123 smith 1 333.20" //here for example only
char strname [20] = { 0 };
int id = 0;
int quarter = 0;
double sales = 0.0;
sscanf (line,"%d %s %d %f", &id, strname, &quarter, &sales);`
Upvotes: 1
Reputation: 58685
Study the standard C++ library. The magic is in std::istream_iterator<>
from <iterator>
, overloading operator>>()
for employee
and using a std::vector<>
:
#include<iostream>
#include<fstream>
#include<iterator>
#include<string>
#include<vector>
struct employee {
int id;
std::string lastname;
int quarter;
double sales;
};
template<class Ch, class Tr>
std::basic_istream<Ch,Tr>& operator>>(std::basic_istream<Ch,Tr>& in, employee& e)
{
return in >> e.id >> e.lastname >> e.quarter >> e.sales;
}
int main(int argc, char* argv[])
{
std::ifstream infile("sales.txt");
std::vector<employee> employees((std::istream_iterator<employee>(infile)),
std::istream_iterator<employee>());
return 0;
}
Upvotes: 4
Reputation: 4887
I'm guessing the commented out portion isn't working? In C++ arrays are indexed starting at 0, so that portion should be instead
for(int j=0; j < 4; j++)
{
list[i].qtrSale[j] = 0.0;
}
Upvotes: 0