Reading database from file c++ -
i'm trying read database file.
here save_base method:
void data_base::save_base() { fstream file; file.open("base.dat", ios::in | ios::out | ios::trunc); if(file.good()==true) { node *p = new node(); p=first; while(p) { file << p->content->connect() << ";" << "\n"; p=p->next; } file.close(); }else{ cout << "err - opening file." << endl; } }
connect method:
string product::connect() { ostringstream do_string; do_string << lp; string new_lp = do_string.str(); ostringstream do_string1; do_string1 << count; string new_count = do_string1.str(); ostringstream do_string2; do_string2 << prize; string new_prize = do_string2.str(); ostringstream do_string3; do_string3 << vat; string new_vat = do_string3.str(); string connected = type + ";" + new_lp + ";" + name + ";" + new_count + ";" + unit + ";" + new_prize + ";" + new_vat; return connected; }
and read_base method:
void data_base::read_base() { fstream file; file.open("base.dat", ios::in); if(file.good()==true) { char data_row[50]; int i=1; while(!file.eof()) { file.getline(data_row,100); string data_content[50]; int j = 0; char *buff; buff = strtok (data_row,";"); while (buff != null) { data_content[j] = buff; buff = strtok (null, ";"); j++; } string type = data_content[0]; int lp; istringstream iss1(data_content[1]); iss1 >> lp; double count; istringstream iss2(data_content[3]); iss2 >> count; double prize; istringstream iss3(data_content[5]); iss3 >> prize; double vat; istringstream iss4(data_content[5]); iss4 >> vat; // sprawdzamy typ obiektu zapisanego w danym wierszu pliku if(type == "product") { product new_prod(lp, data_content[2], count, data_content[4], prize, vat); product *new_product = new product(new_prod); this->add(new_product); } i++; } file.close(); }else{ cout << "err opening file." << endl; } }
i'm adding products database , works fine. saving file works great. main problem when i'm trying read database file. reading database file works fine, @ end, application won't end itself. think there still buffers close. don't know or how close them.
honestly - have quite lot of problems going on in code, , i'd suggest main problem you're perhaps still wrestling encapsulation. code uses mix of c , c++ styles guaranteed make code hard read , maintain, , that's why you're here , people struggling give answer.
that said, problem looks in save you're calling "new node()" looks you'd saving ... nothing. shouldn't querying existing value within product? edit: ah - no, re-assign "p = first" now, see. happens node allocated on previous line?
you have potential stack-clobber when of lines exceed 50 bytes:
char data_row[50]; int i=1; while(!file.eof()) { file.getline(data_row,100);
if have use char arrays, habbit of using sizeof:
file.getline(data_row, sizeof(data_row));
it took me few moments figure out istringstreams - you're trying convert strings numbers? simpler , more efficient written as:
unsigned int lp = atoi(data_content[1].c_str()); or unsigned int lp = strtoul(data_content[1].c_str(), null, 10);
your read_base function, part of database, knows waaaay data records. need encapsulate record population away read_base looks more like:
void data_base::read_base() { fstream file("base.dat", ios::in); if(file.good() == false) { cout << "error opening file." << endl; return; } for(size_t rowno = 0; !file.eof(); ++rowno) { row* row = data_type::make_object_from_row(file); if(row != nullptr) this->add(row); } } }
you may need "factory pattern" how implement data_row base type let this. in short, make product inherit data_type above works. data_type::make_object_from_row read first part of row , enumerate type can like:
data_type* data_type::make_object_row_row(istream& file) { switch(get_type(file)) { case data_type_product: return new product(file); case data_type_person: return new person(file); default: clog << "invalid type in database: " << type << endl; return nullptr; } }
(this 1 possible approach).
Comments
Post a Comment