adatok idonkenti kiirasa fajlokba

Kezdőlap Fórumok Programozás adatok idonkenti kiirasa fajlokba

10 bejegyzés megtekintése - 1-10 / 25
  • Szerző
    Bejegyzés
  • #2197375
    uzsolt
    Felhasználó

      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.

      #2197376
      ktibi
      Felhasználó

        Koszi, ez nekem is nyilvanvalo, csak a kivitelezes problemas… (hogyan  ???)

        #2197377
        pointux
        Felhasználó
          ktibi 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.

          #2197378
          ktibi
          Felhasználó
            vizsla 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…

            #2197379
            pointux
            Felhasználó

              De, 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 egy

              Code:
              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.)

              #2197380
              ktibi
              Felhasználó

                Amí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)

                #2197381
                pointux
                Felhasználó

                  Ja, é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.)

                  #2197382
                  ktibi
                  Felhasználó
                    vizsla 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…).

                    #2197383
                    pointux
                    Felhasználó

                      Akkor 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ő file                                                                                 

                                              filename_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.)

                      #2197384
                      pointux
                      Felhasználó

                        A 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!” );
                                }
                        }

                      10 bejegyzés megtekintése - 1-10 / 25
                      • Be kell jelentkezni a hozzászóláshoz.