Kezdőlap › Fórumok › Programozás › adatok idonkenti kiirasa fajlokba
- This topic has 24 hozzászólás, 4 résztvevő, and was last updated 15 years, 6 months telt el by
pointux.
-
SzerzőBejegyzés
-
2009-12-16-09:33 #2197375
Nem vagyon nagy C++-os, de az már tisztán látszik, hogy mindig más fájlt kell megnyitnod, nem pedig mindig a data.dat-ot.
2009-12-16-09:39 #2197376Koszi, ez nekem is nyilvanvalo, csak a kivitelezes problemas… (hogyan ???)
2009-12-16-11:55 #2197377ktibi wrote:Koszi, ez nekem is nyilvanvalo, csak a kivitelezes problemas… (hogyan ???)Bár, mondjuk, nem egészen értem a problémát, de növekvő indexű file-neveket pl. így lehet előállítani.
Code:#include
#include
#include#define FILENAME_PUFFER_SIZE 32
int main () {
char filename_puffer [ FILENAME_PUFFER_SIZE ];
int filename_index;
int filename_size;for (
int filename_index = 1; filename_index = FILENAME_PUFFER_SIZE )
exit ( -1 );std::cout << filename_puffer << std::endl;
}
}FILENAME_PUFFER_SIZE a túlcsordulás elkerülése miatt van, itt kilépéssel.
A számozások 1-10-ig „kétjegyűek”, az abc sorrend miatt. (Persze, nem kötelező. -„.2”.)
Ez, persze csak kiírja a fileneveket.2009-12-16-22:24 #2197378vizsla wrote:Bár, mondjuk, nem egészen értem a problémát,…Valojaban „csak” annyi, hogy adatokat, mondjuk, egesz szamokat generalok egy ciklusban es ezeket kiiratom egy fajlba. Tovabbfejlesztve azt szeretnem, hogy bizonyos idokozonkent, mondjuk „n” lepesenkent (ugye ezzel parameterezem az idot) az addig legeneralt adatokat akarom kiirni fajlba. Algoritmikusan igy gondolnam (leegyszerusitve)
Code:int valzoto = 1;ofstream f1;
f1.open(„adat_1.dat”);
ofstream f2;
f1.open(„adat_2.dat”);for (int i=0; i=0 && i=10 && i<20){
f2 << valtozo << endl;
f2.close();
}else{// do nothing
}
}Megnyitok n db file-t es csak akkor zarom be oket, ha megvan a kello adatmennyiseg. Csak a fenti kod igy ugye hibas…
2009-12-17-08:35 #2197379De, minek ehhez a két ciklus, és minek ehhez a sok file?
Amíg nem értem a problémát, addig nem tudom a megoldást.
Jelen pillanatban – azzal az információkkal, amivel rendelkezek – elég egy file, egy ciklus és a ciklusban fut egy „generálás” függvény x paraméterekkel.
Sőt mivel C++-ban vagyunk elegáns megoldás lehet, hogy a generálás egy osztály, melynek van egyCode:std::o(f)stream& operator<< ( std::o(f)stream& ostream, GeneratingClass& generatingClass )tagfüggvénye. Ezzel megvalósítható, egy saját, akár láncolt formázott adatkiírás. (Bár jelen esetben lehet, hogy a láncolásnak nincs értelme, mert nem kell, hogy a megoldás képlékeny legyen. Minden esetben ugyanaz a formázás.)
2009-12-17-10:16 #2197380Amíg nem értem a problémát, addig nem tudom a megoldást.
Jobbnak latom, ha konkretizalom: az alapfeladat az alabbi kod… Itt egy nagy for() ciklusban annyit csinalok , hogy vektorokat forgatok es egy z-tengellyel bazart szoguk koszinuszat iratom ki a „dataA.dat” file-ba. De ez csak egy db. fajl ugye az egesz ciklusra, mely N db. szamot (erteket) tartalmaz. Ugyanez a helyzet a „dataB.dat” file-lal is, ez is csak egy db.
Viszont azt szeretnem, hogy bizonyos lepesenkent (mondjuk, ha N=100 a for() cilusban, akkor pl. 20 lepesenkent) az addig generalt „ize[]” szog ertekeket kiirja fajlokba, azaz: 20 lepes utan lesz egy dataA_1.dat file (20 sorral), 40 lepes utan dataA_2.dat file (40 sorral; a dataA_1.dat-beli sorok + az ujonnan kapott 20 ertek), majd 60 lepes utan dataA_3.dat 60 sorral,..stb
Egyszerűbb, ha csatolom a .cpp kodot, reszletesen lasd a csatolmanyt. (A .txt kiterjesztest csak .cpp-re kell atnevezni; sajnos csak .txt-t fogad csatolmany kiterjesztesnek)
2009-12-17-11:42 #2197381Ja, értem, nem szétszedni akarod az adatokat, hanem i-edik file-ban, az i-edik lépésig tárolni az összes eredményt.
Bár nem értem, hogy miért jó ez, de nem is lényeges.Ebben az esetben, ha kevés adatról van szó: pár ezer mátrix, akkor az egészet a memóriában tárolnám és utána csinálnám a file-okat. De akkor ezek szerint nem kell két egymásba ágyazott ciklus, csak 1.
Ha 100 millió darab mátrix van, akkor nem fér bele a memóriába, akkor csak 20-at számoltatnék (mindig) és az előtte lévő file-t átmásolnám és bővíteném a 20 adattal.Melyik lesz a nyerő?
Az összes adat belefér a memóriába, vagy csak a blokknyi méretű (jelenleg 20)?
Ha ezt tisztáztuk, akkor már fel tudjuk írni a filekészítő algoritmust. (A Matrix/Akarmi osztály, az másik problémakör – ettől független. Nyílván az operator<< megold egy darab adat formázott kiírását… az most legyen adott.)Amúgy itt nincs valami gond, mert úgy látom, mintha az alfa konstans lenne a cikluson belül? (Viszont a vektorok, meg a cikluson belül vannak. Ez így cpu pocséklás.)
2009-12-17-12:12 #2197382vizsla wrote:Melyik lesz a nyerő?
Az összes adat belefér a memóriába, vagy csak a blokknyi méretű (jelenleg 20)?Szerintem a blokkos megoldas lenne nyero, mivel eleg sok (akar 1-10 millio) ize[]-t akarok generalni.
Valojaban, ahogy a program is lefut, 1 db 3x3as matrixom lesz (de a ciklusban ugye matrixokat adogatok ossze, akar 1 milliot is…).
2009-12-17-12:51 #2197383Akkor valami ilyesmire gondoltam:
SIZE_BLOCK = dinamikus/statikus blokk méret (nálad, jelenleg 20)
SIZE = din./stat. összes adat (most 100)Code:float ize [ SIZE_BLOCK ];// blokkokra bontás
//(%-os rész, akkor kell, ha az adatok nem oszthatóak maradék nélkül a blokkal)
for (
int block = 0;
block < ( SIZE / SIZE_BLOCK ) + ( ( SIZE % SIZE_BLOCK ) ? 1 : 0 )
block ++
) {
// blokknyi adat kiszámolása
for ( int data = 0; data 0 ) {
// ebben az esetben már létezik file
// tehát át kell másolni az akár x millió adatot// egyel régebbi file, majd új nevének generálása
// ha az index 1-nél kezdődik, akkor a block indexet növelni kell 1-gyel
// a memória ellenőrzést most kihagyom
filename_size = snprintf (
oldname, FILENAME_PUFFER_SIZE, „data_%2.2d.dat”, block – 1
);
filename_size = snprintf (
newname, FILENAME_PUFFER_SIZE, „data_%2.2d.dat”, block
);
// adatok átmásolása (teljesen mindegy milyen módszerrel)
} else {
// ez még az első filefilename_size = snprintf (
newname, FILENAME_PUFFER_SIZE, „data_%2.2d.dat”, block
);
}// az új adatok írása mindegyiknél kell (itt lehet nyitni bővítésre!, zárni a file-t)
for ( int data = 0; data < SIZE_BLOCK; data ++ ) {
file_ize_print_format ( fstream, ize [ i ] );
}}
Ha az izék generálásához szükségesek az előző file-ok, akkor a „// blokknyi adat kiszámolása” résznél kell előállítani az oldname-et (a legutolsó) és megnyitni olvasásra, vagy bármi más file-t is. (Akkor egy for ciklussal végig lehet futni az adatokon.)
De azt tartsd szem előtt, hogy pl. 8 bites adatokból 1 millió darab még mindig belefér 1 MB RAM-ba. (3 * 1 millió db 64 bites szám még mindig csak 24 MB), tehát komolytalan mennyiség egy mai gépnek. (Ilyen esetekben felesleges egy a file-blokkos cirkusz, ráadásul időt takarítasz meg.)2009-12-17-13:24 #2197384A poén kedvéért emeljük 100 millió db float-ra a tétet.
Code:int main ()
size_t num = 100000000;
float *ize = NULL;ize = ( float * ) malloc ( sizeof ( float ) * num );
if ( ize != NULL ) {
printf ( „%d MB? This is pite! This is nothing!n”, sizeof ( float ) * num / 1024 / 1024 );
free ( ize );
} else {
printf ( „Sorry, dude!” );
}
} -
SzerzőBejegyzés
- Be kell jelentkezni a hozzászóláshoz.
legutóbbi hsz