|
[ hninel @ 25.05.2004. 21:35 ] @
| Code:
#include <iostream>
#include <fstream>
#include <conio.h>
#include <vector>
#include <string>
using namespace std;
template <typename elemType>
void readFromFile(string filename, vector <elemType> &vec)
{
fstream iFile;
iFile.open (filename.c_str(), ios::in | ios::binary);
if (!iFile)
{
cerr << "\nNemogu otvoriti " << filename;
return;
}
while (iFile)
{
elemType *obj=new elemType;
iFile.read( (char*)obj, sizeof(elemType));
vec.push_back(*obj);
}
iFile.close();
}
template <typename elemType>
void writeToFile(string filename, vector <elemType> &vec)
{
ofstream oFile;
oFile.open(filename.c_str(), ios::trunc | ios::binary | ios::out);
if (!oFile)
{ cerr << "\nNemogu da otvorim ya upis fajl: " << filename;
return;
}
for (int i=0; i<vec.size(); i++)
{
oFile.write( (char *)&vec[i], sizeof(elemType));
}
oFile.close();
}
template <typename elemType>
void showAll(vector <elemType> &vec)
{
for (int i = 0; i<vec.size(); i++)
{
cout << vec[i] << endl;
}
}
void main (void)
{
vector <string> vecStr;
strting str;
char c;
do
{
cout << "\nUnesite rijec: " << endl;
cin >> str;
vecStr.push_back(str);
cout << "\Ako zelite jos pritisnite 'y'" << endl;
cin >> c;
}while (c=='y' || c=='Y');
writeToFile("asd.dat", vecStr);
vecStr.clear();
readFromFile("asd.dat", vecStr);
showAll(vecStr);
getch();
return;
}
Ovo je code s kojim imam problema. Kada unesem string,kao u gornjem primjeru i nesto upisem (par stringova) te to snimim u file i onda iscitam u vector on mi pokazuje nekakve znakove koji nemaju veze sa mojim tekstom.
Isto tako kada umjesto stringa stavim recimo int, dobijem, kada iscitam ponovo iz filea u vector, moje brojeve i jos jedan 6-sifreni broj.
Moze li mi neko malo ovo objasniti.
Ovaj code je samo jednostavniji jer sa ovim template-om kojim citam i pisem u fajl hocu da radim sa drugim objektima klasa koje napravim. Do sada imam samo probleme.
Hvala unaprijed.
////////////////////
|
[ filmil @ 25.05.2004. 22:11 ] @
Koliko vidim, ti bi želeo da napraviš perzistentne objekte uz pomoć šablona.
Na žalost, to neće ići tako kako si zamislio. Najpre je zapisivanje pogrešno jer ti pokušavaš da upišeš &vec[ i] koji je forsirano pretvoren u char*. Za upisivanje u fajl se onda koriste pravila koja važe za ASCIIZ, što u opštem slučaju ne mora da bude primenljivo na tvoj objekat i u slučaju stringa u primeru ne daje tačan rezultat.
Drugi je problem sa time što ćeš, ukoliko je objekat agregat (a praktično svaki složeni objekat pa i string jeste agregat) na disk upisati niz nekakvih pointera koji zavise od trenutne memorijske slike programa - koja se menja praktično iz takta u takt. Drugim rečima, ono što si zapisao na disk je potpuno beskorisno sa stanovišta čuvanja objekata.
Ispravna perzistencija je malko komplikovana stvar; nisam čuo za neku jednostavnu c++ biblioteku za to. Koliko vidim ni http://www.boost.org nema neki pametan savet oko toga. Perzistencija u Javi na primer je praktično ugrađena u sve objekte koji mogu da se „serijalizuju“, dakle deo je dizajna jezika. C++ koliko znam to nema.
f
[ Dragi Tata @ 26.05.2004. 16:21 ] @
Code:
#include <iostream>
#include <fstream>
#include <conio.h>
#include <vector>
#include <string>
using namespace std;
template <typename elemType>
void readFromFile(string filename, vector <elemType> &vec)
{
fstream iFile;
iFile.open (filename.c_str(), ios::in | ios::binary);
if (!iFile)
{
cerr << "\nNemogu otvoriti " << filename;
return;
}
while (iFile.peek() != char_traits<char>::eof ( ))
{
elemType *obj=new elemType;
//iFile.read( (char*)obj, sizeof(elemType));
iFile >> *obj;
vec.push_back(*obj);
}
iFile.close();
}
template <typename elemType>
void writeToFile(string filename, vector <elemType> &vec)
{
ofstream oFile;
oFile.open(filename.c_str(), ios::trunc | ios::binary | ios::out);
if (!oFile)
{ cerr << "\nNemogu da otvorim ya upis fajl: " << filename;
return;
}
for (int i=0; i<vec.size(); i++)
{
//oFile.write( (char *)&vec[i], sizeof(elemType));
oFile << vec[i];
}
oFile.close();
}
template <typename elemType>
void showAll(vector <elemType> &vec)
{
for (int i = 0; i<vec.size(); i++)
{
cout << vec[i] << endl;
}
}
void main (void)
{
vector <string> vecStr;
string str;
char c;
do
{
cout << "\nUnesite rijec: " << endl;
cin >> str;
vecStr.push_back(str);
cout << "Ako zelite jos pritisnite 'y'" << endl;
cin >> c;
}while (c=='y' || c=='Y');
writeToFile("asd.dat", vecStr);
vecStr.clear();
readFromFile("asd.dat", vecStr);
showAll(vecStr);
getch();
return;
}
Samo treba koristiti operatore >> i << umesto one nebuloze sa "sirovim" pisanjem.
[ filmil @ 26.05.2004. 16:42 ] @
... i povrh toga, objekti moraju da znaju da se „zapišu“ i „iščitaju“ uz pomoć operatora << i >>. Za jednostavne objekte to nije problem, ali kada imaš međuzavisnosti, stvari se komplikuju.
f
[ Dragi Tata @ 26.05.2004. 16:52 ] @
Naravno. Za složenije slučajeve treba koristiti biblioteke kao što je Boost serialization library
http://www.rrsd.com/boost/
ili nešto slično.
Inače, u poređenju sa Javom, C++ ima statički objektni model u kome ima malo mesta za refleksiju, serijalizaciju i slične stvari. To ima svoje nedostatke, ali i prednosti (efikasnost, type safety...).
[ Reljam @ 26.05.2004. 16:54 ] @
Na koj nacin je C++ objektni model vise type-safe od .NETovog? Brzi, da. Type-safe, ne.
[ Dragi Tata @ 26.05.2004. 17:07 ] @
Hehe, ne sećam se da sam spomenuo .NET, ali kad se već javljaš, evo jedan prost primer: uz pomoć refleksije, možeš lako da pristupiš privatnim članovima klase.
[ Dragi Tata @ 26.05.2004. 17:19 ] @
I da ne zaboravim. Dynamic method invocation (podržavaju ga i Java i .NET) ume da bude zgodna stvar, ali direktno ugrožava type safety. Ako pozoveš metod koji ne postoji, dobićeš run-time izuzetak. Kod C++a, tako nešto nije moguće - ako ga kompajler propusti, znači metod postoji.
[ Reljam @ 26.05.2004. 17:24 ] @
To nije type-safety issue. I u C++u ti mozes da pristupis private clanovima sa malo kopanja po memoriji.
.NET je cak i vise type safe. Ti u C++u mozes da uradis ovo:
A *a = new A;
[... par hiljada linija koda i nekoliko poziva dalje...]
B *b = (b*) a;
i da tako b-u dodelis pointer na a iako ta dva nemaju nikakve veze (prilikom derefenciranja b, stvar puca). Lose kastovanje je mnogo veci problem od pozivanja private metoda na silu.
Type-safety se odnosi na sprecavanje nehoticnih gresaka. Ako neko zeli namerno da zaobidje tu sigurnost u svom programu, to je njegova stvar.
[ Dragi Tata @ 26.05.2004. 17:59 ] @
.NET ima bolji run-time type safety (baci izuzetak umesto da prsne kod lošeg kastovanja), ali je compile-time type safety slabiji. Dinamička invokacija metoda je jedan primer, a nedostatak type-safe kontejnera je još ozbiljniji problem (mada bi to trebalo da bude sređeno kad stignu genericsi).
[ Reljam @ 26.05.2004. 18:29 ] @
Ja sve vreme racunam na genericse... ;) .NET 2.0 je lepa stvar.
U svakom slucaju, sa genericsima, type safety u .NETu je bolji nego u C++u, i naravno refleksija omogucava gomilu novih scenarija. Naravno, sve je to na ustrp performansi, tako da treba izabrati pravi alat za pravu priliku.
[ hninel @ 03.06.2004. 20:24 ] @
Da se malo vratimo na temu...
Rijesio sam problem tako da cu pisati i citati iz file-a da ne koristim ios_base::binary, jer mi nikako ne vraca ispravno podatke.
Imam slijedeci code
Code: template <typename T>
vector <T> RWdata<T>::readFromFile(string filename)
{
vector <T> tmp;
T opV;
ifstream in(filename.c_str());
in.seekg(0, ios_base::end);// postavi pointer na pocetak file-a
int sizeOfFile = in.tellg();
// pointer ide na kraj i vraca velicinu file-a
in.seekg(0, ios_base::beg);// vrati pointer na pocetak
if (!in)
{
cerr << "\nNemogu da otvorim fajl: " << filename;
return tmp;
}
if (sizeOfFile)// Ako file ima ikakvu velicinu tj. ako ima objekata
{
// Ovdje ima problem:
// Ucitava jedan vise objekat u vector (zadnji objekat u nizu);
// Kroz petlju prolazi jednaput vise nego sto ima objekata u file-u
while (in)
{ in >> opV;
tmp.push_back(opV);
}
}
else // u suportnom je prazan
{
cout << "\nFajl je prazan\n";
}
in.close();
return tmp;
}
Ovdje imam problem jer mi ucitava jedan vise objekat u vector i to zadnji ucitani. U cemu je stvar...
Hvala unaprijed.
/////
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|