Tiedon lukeminen tiedostosta

pihalla kuin lumiukk

Miten saan luettua tiedot tiedostosta siten että käytän niiden lukemisessa yli- ja aliluokissa käytettyjä muuttuja tietojäseniä? Tiedosto on binäärimuodossa.

Käyttäjältä on kysytty tietoja. Osa muuttujista on yli-luokassa ja osa aliluokassa. Tiedot tallentuvat tiedostoon.

Yliluokkaan olen tehnyt metodin (jäsenaliohjelman), jossa tiedosto avataan (fstream) ja tiedot tulostetaan. Tässä metodissa luetaan vain yliuokan jäsenmuuttujat, koska aliluokan jäsenmuuttujiin ei ole "pääsyä". Tätä metodia kutsuttan aliluokan vastaavanlaisessa metodissa ensin.

Samoin olen tehnyt aliluokkaan samanlaisen metodin, siinä siis tiedostosta luetaan vain aliluokan muuttujat.

Nyt ongelma on siis sse että muuten tiedostoston tiedot tulostuvat hienosti eli nuo yliluokan muuttujat. Aliluokan metodilla luetaan taas uudestaan tiedoston alusta ja "väärät" tiedot tulostuvat.

Onko tämä oikea tapa toteuttaa tällainen? (Minua vähän ihmetyttää miksi tähän pitää sotkea nuo luokkien jäsenmuuttujat? Paitsi tietenkin jos vaikka noita halutaan muuttaa.) Miten luen tiedostosta esim. viidennenne tiedon aliluokan jäsenmuuttujaan?

Pitäisikö tiedosto lukea ihan vain kokonaisuutena ja tulostaa?

Miten te tekisitte?

13

749

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Minä laitan tavaran johonkin structiin minkä kirjoitan levylle tai luen sieltä. Sieltä voi toki sitten siirtää tavarat luokan jäsenmuuttujiin, samalla kun huolehtii tavujärjestyksestä.

    • Ei oo vaikeeta

      Yksinkertaisesti tuon voi toteuttaa tutkimalla delimittereitä ja käyttämällä niitten perusteella luotuja alimerkkijonoja, jotka tiedostosta löytymisensä muunnetaan luokan ominaisuuden edellyttämään muotoon kuten esimekiksi kokonaisluvuksi (tidosto voi olla tallennettu tekstimuodossa tai binäärinä, mikä tulee ottaa huomioon jollain muulla soveluksella kuin sillä, jolla se on luotu, tiedoston sisältöä tutkittaessa). Virtuaalijäsenfunktioita käyttämällä voidaan luokasta periytyneissä luokissa vaikuttaa luku- tahi mihin tahansa järjestykseen helposti.

    • Olio-Otus
    • Ogma

      Koska viestistä puuttuu jonkun verran tietoa ongelman asettelusta, niin vastaus on sen mukainen ;-)
      Huom! Jäsenmuuttujien ongelmasta usein pääsee eroon setterien ja getterien käytöllä.

      Ainakin yksi huomio on se, että yhdenkään luokkasi tehtäviin ei pitäisi kuulua fstreamin avaaminen ja sulkeminen, koska se ei ole persistenttiyden idea. fstreamiin tavaran tuuppaaminen ja sieltä lukeminen onkin eri asia. Eli ensinnäkin hoida fstreamin elinkaari jossain muualla kuin ko. luokissa.

      Koska et kerro niin oletan aliluokka B täydentää yliluokkaa A lisäämällä A:n tyyppiin jotain lisätietoa b.
      Jos olet A:lle määritellyt getterin int get_a() ja B:lle getterin float get_b() niin homma on melko yksinkertaista. (Huom! Tuskin menee käätäjästä läpi mutta ideatasolla pitäisi toimia)
      ofstream a; B_o.set_a( a );
      ifstream >> b; B_o.set_b( b );

      Muista oikea lukujärjestys.

      tietysti voit tehdä myös

      ofstream& operator > (ifstream& os, const A&);
      ofstream& operator > (ifstream& os, const B&);

      Jolloin homma toimii
      ofstream (A)B_o;
      ifstream >> B_o;

      Voit myös tehdä noista jäsenoperaatioita em. luokkiin. Tai käyttä valmiita kirjastoja.

      Toisaalta joskus perinnän voi korvata assosiaatiolla eli luokka ei sisällä attribuutteina itse dataa vaan rakenteen (esim. map tai jopa list), joka säilöö ominaisuuksia (CProperty). Tällöin aliluokka vain luotaessa lisää ominaisuustauluun ne entryt, jotka se tuntee. Tällöin ei välttämättä tarvitse tuntea yliluokkaa ollenkaan vaan riittaa kun streamilla antaa aliluokan, joka osaa dumpata informaation oikeassa muodossa oikeaan suunntaan (taulusta virtaan ja päinvastoin). No joo, tämä saattaa olla ylikurssin asiaa, joten se siitä.

      • 454452345

        Mitähän tietoja vielä kaipailet?

        Koko ongelman ydin on siis, miten tiedostosta luetaan tietoja ja miten tiedot tulostetaan... Kuvitellaan että tilanne että tiedostoon tallennetaan käyttäjältä kysyttävät tiedot: nimi, ikä, ammatti. Nimi ja ikä ovat yliluokan tietojäseniä ja ammatti on aliluokan tietojäsen. (Näiden tiedostoon tallentaminen on ok.)

        Jos tuota aliluokan tietoa ei tarvitsisi lukea ja tulostaa näytölle, en tätä ihmettelisi.

        Luen tiedostoa näin yliluokan metodilla.

        ifstream tiedLuku("Tiedosto.txt", ios::binary|ios::in);

        while(!tiedLuku.eof())
        {
        tiedLuku.read( (char*) &henkilot[i].nimi, sizeof(nimi) );
        tiedLuku.read( (char*) &henkilot[i].ika, sizeof(ika) );

        i ;
        }

        Tämä toimii ok.

        Vastaavalla tavalla yritän lukea tiedostosta tiedon joka talletetaan tiedostoon aliluokaan tietojäsenenä eli

        ifstream tiedLuku("Tiedosto.txt", ios::binary|ios::in);

        while(!tiedLuku.eof())
        {
        tiedLuku.read( (char*) &ammatit[i].tyyny, sizeof(ammatti) );

        i ;
        }
        Tämä ei toimi ok, lukee tiedostosta ensimmäisen tiedon (joka on siis nimi.)

        Tiedostojen lukemiset ovat luokkakohtaisia metodeja.

        Luulen että opettaja on tarkoittanut että homma hoidetaan jotenkin hyvin yksinkertaisella tavalla. Ainoa esimerkki, jossa tiedostosta luetaan tietoja ja tulostetaan ne on kuitnekin sellainen jossa ei ole aliluokkaa.

        Juu ja opettajalta on asiaan yritetty saada neuvoa...valitettavasti turhaan vaikka koko koodi oli nähtävissä.
        Mahtavaa.


      • Ei oo vaikeeta
        454452345 kirjoitti:

        Mitähän tietoja vielä kaipailet?

        Koko ongelman ydin on siis, miten tiedostosta luetaan tietoja ja miten tiedot tulostetaan... Kuvitellaan että tilanne että tiedostoon tallennetaan käyttäjältä kysyttävät tiedot: nimi, ikä, ammatti. Nimi ja ikä ovat yliluokan tietojäseniä ja ammatti on aliluokan tietojäsen. (Näiden tiedostoon tallentaminen on ok.)

        Jos tuota aliluokan tietoa ei tarvitsisi lukea ja tulostaa näytölle, en tätä ihmettelisi.

        Luen tiedostoa näin yliluokan metodilla.

        ifstream tiedLuku("Tiedosto.txt", ios::binary|ios::in);

        while(!tiedLuku.eof())
        {
        tiedLuku.read( (char*) &henkilot[i].nimi, sizeof(nimi) );
        tiedLuku.read( (char*) &henkilot[i].ika, sizeof(ika) );

        i ;
        }

        Tämä toimii ok.

        Vastaavalla tavalla yritän lukea tiedostosta tiedon joka talletetaan tiedostoon aliluokaan tietojäsenenä eli

        ifstream tiedLuku("Tiedosto.txt", ios::binary|ios::in);

        while(!tiedLuku.eof())
        {
        tiedLuku.read( (char*) &ammatit[i].tyyny, sizeof(ammatti) );

        i ;
        }
        Tämä ei toimi ok, lukee tiedostosta ensimmäisen tiedon (joka on siis nimi.)

        Tiedostojen lukemiset ovat luokkakohtaisia metodeja.

        Luulen että opettaja on tarkoittanut että homma hoidetaan jotenkin hyvin yksinkertaisella tavalla. Ainoa esimerkki, jossa tiedostosta luetaan tietoja ja tulostetaan ne on kuitnekin sellainen jossa ei ole aliluokkaa.

        Juu ja opettajalta on asiaan yritetty saada neuvoa...valitettavasti turhaan vaikka koko koodi oli nähtävissä.
        Mahtavaa.

        Funktion read(...) määrittelyssä on tilaisuus työnnellä luettuja tietoja sinne sun tänne eli jossain määriteltyihin tietojäseniin, luokan omiin tai perimiin ominaisuuksiin, atribuutteihin. Näihin voi päästä päästä periytyneen luokan oliosta käsiksi suoraan, elleivät ne ole tyyppiä private emoluokassaan. Tällöinkin niihin pääsee käsiksi emoluokan käsiksipääsyfunktioitten, metodien kautta.


      • yhä pihalla
        Ei oo vaikeeta kirjoitti:

        Funktion read(...) määrittelyssä on tilaisuus työnnellä luettuja tietoja sinne sun tänne eli jossain määriteltyihin tietojäseniin, luokan omiin tai perimiin ominaisuuksiin, atribuutteihin. Näihin voi päästä päästä periytyneen luokan oliosta käsiksi suoraan, elleivät ne ole tyyppiä private emoluokassaan. Tällöinkin niihin pääsee käsiksi emoluokan käsiksipääsyfunktioitten, metodien kautta.

        Luokkien kaikki tietojäsenet ovat private. Eli ei pääse käsiksi perityyneen luokan oliosta käsin.


        MInä vähän luulen ettei tämä ongelma ydin ole teille auennut. Ongelman ydin on se että kaikki nuo tiedot talletetaan samaan tiedostoon, ei siis tiedostossa on tietoja seuraavassa järjestyksessä:
        nimi...ika...ammatti nimi...ika...ammatti jne

        Nyt kun avaan fuktiossa tiedoston lukemista varten luen tiedostosta nimi- ja ika- tiedot henkilot -taulukkoon. Seuraavaksi avaan tiedoston lukemista varten, jossa yritän lukea tuon ammtti-tiedon ammatit taulukkoon, niin se lukee tiedoston alusta nimi-tieto, eikä vähän "kauempana" oleva ammattitieto.

        Jos tallennan nuo erillisiin tiedostoihin ja luen tiedostot noihin omiin taulukoihin niin tällöin homma toimii.

        Taulukoiden sisältöjen tulostaminen onnistunee sitten ihan vain [i]:tä rullaamalla jne...

        Miten seekg()-funktiota käytetään, jotta päästään tiedostossa oikean tiedon kohdalle?


      • Sanoin mä joo
        yhä pihalla kirjoitti:

        Luokkien kaikki tietojäsenet ovat private. Eli ei pääse käsiksi perityyneen luokan oliosta käsin.


        MInä vähän luulen ettei tämä ongelma ydin ole teille auennut. Ongelman ydin on se että kaikki nuo tiedot talletetaan samaan tiedostoon, ei siis tiedostossa on tietoja seuraavassa järjestyksessä:
        nimi...ika...ammatti nimi...ika...ammatti jne

        Nyt kun avaan fuktiossa tiedoston lukemista varten luen tiedostosta nimi- ja ika- tiedot henkilot -taulukkoon. Seuraavaksi avaan tiedoston lukemista varten, jossa yritän lukea tuon ammtti-tiedon ammatit taulukkoon, niin se lukee tiedoston alusta nimi-tieto, eikä vähän "kauempana" oleva ammattitieto.

        Jos tallennan nuo erillisiin tiedostoihin ja luen tiedostot noihin omiin taulukoihin niin tällöin homma toimii.

        Taulukoiden sisältöjen tulostaminen onnistunee sitten ihan vain [i]:tä rullaamalla jne...

        Miten seekg()-funktiota käytetään, jotta päästään tiedostossa oikean tiedon kohdalle?

        Mitäs mä sanoin?
        http://keskustelu.suomi24.fi/listmessage/8982963/43498471


      • 2525
        Sanoin mä joo kirjoitti:

        Mitäs mä sanoin?
        http://keskustelu.suomi24.fi/listmessage/8982963/43498471

        jotain sanoit, mutta kun en edes ymmärrä mitä sanot : )

        miten tuo liittyy siihen että minun pitäisi pystyä lukemaan tiedostossa tietyssä kohtaa oleva tieto. Ja huomaa että noitahan voi siis olla vaikka sata siellä tiedostossa

        nimi...ika...ammatti nimi...ika...ammatti n 1


      • Järjestys olla pitää
        2525 kirjoitti:

        jotain sanoit, mutta kun en edes ymmärrä mitä sanot : )

        miten tuo liittyy siihen että minun pitäisi pystyä lukemaan tiedostossa tietyssä kohtaa oleva tieto. Ja huomaa että noitahan voi siis olla vaikka sata siellä tiedostossa

        nimi...ika...ammatti nimi...ika...ammatti n 1

        Se ohjelma kirjoittaa ne tiedot joka kerta samalla tavalla => ne voi myös lukea joka kerta samalla tavalla (myös samalla eri tavalla kuin tietojen alkuperäinen tallentaja on ajatellut). Tietoja ei kirjoiteta pötköön, tiedot on jotenkin eroteltava toisistaan => on käytettävä delimittereitä, joiden paikat voidaan laskea => tietyssä kohdassa tiedostoa olevan delimitterin jälkeen tulee luettaessakin aina sama tieto. Siksi täytyy ensin selvittää, miten ja missä järjestyksessä tiedot on tiedostoon kirjoitettu. Nerokasta!


      • It's easy
        Järjestys olla pitää kirjoitti:

        Se ohjelma kirjoittaa ne tiedot joka kerta samalla tavalla => ne voi myös lukea joka kerta samalla tavalla (myös samalla eri tavalla kuin tietojen alkuperäinen tallentaja on ajatellut). Tietoja ei kirjoiteta pötköön, tiedot on jotenkin eroteltava toisistaan => on käytettävä delimittereitä, joiden paikat voidaan laskea => tietyssä kohdassa tiedostoa olevan delimitterin jälkeen tulee luettaessakin aina sama tieto. Siksi täytyy ensin selvittää, miten ja missä järjestyksessä tiedot on tiedostoon kirjoitettu. Nerokasta!

        Miten saa tietää, missä järjestyksessä ja millä delimittereillä tidot on sinne tiedostoon kirjoitettu? Se on ihan helppoa! Varataan koko keskusmuistin täydeltä (ja svappi päälle) bufferille tilaa ja luetaan tedosto yhtenä möykkynä bufferiin ja sitten vaan katsotaan, mitä siellä on ja lasketaan delimittereitten paikat näytöltä!


      • onhan se helppoa
        It's easy kirjoitti:

        Miten saa tietää, missä järjestyksessä ja millä delimittereillä tidot on sinne tiedostoon kirjoitettu? Se on ihan helppoa! Varataan koko keskusmuistin täydeltä (ja svappi päälle) bufferille tilaa ja luetaan tedosto yhtenä möykkynä bufferiin ja sitten vaan katsotaan, mitä siellä on ja lasketaan delimittereitten paikat näytöltä!

        Niin onhan se helppoa...

        ei kyllä ole hajuakaan miten muuten tuota tiedostoa voidaan lukea kuin miten olen tuonne ylös laittanut

        while(!tiedLuku.eof())
        {
        tiedLuku.read( (char*) &henkilot[i].nimi, sizeof(nimi) );
        tiedLuku.read( (char*) &henkilot[i].ika, sizeof(ika) );

        i ;
        }

        eli miten sama tehdään niin että luen koko tiedoston bufferiin? Tai voinko lukea nuo aliohjelmassa määriteltyihin muuttujiin tai edes johonkin.

        Vittu että tämä C on perseestä. C:llä tämän olisi jo tehnty mutta noiden saatanan private tietojäsenten...


      • Nyt se selviää
        onhan se helppoa kirjoitti:

        Niin onhan se helppoa...

        ei kyllä ole hajuakaan miten muuten tuota tiedostoa voidaan lukea kuin miten olen tuonne ylös laittanut

        while(!tiedLuku.eof())
        {
        tiedLuku.read( (char*) &henkilot[i].nimi, sizeof(nimi) );
        tiedLuku.read( (char*) &henkilot[i].ika, sizeof(ika) );

        i ;
        }

        eli miten sama tehdään niin että luen koko tiedoston bufferiin? Tai voinko lukea nuo aliohjelmassa määriteltyihin muuttujiin tai edes johonkin.

        Vittu että tämä C on perseestä. C:llä tämän olisi jo tehnty mutta noiden saatanan private tietojäsenten...

        Ei tiedostoa voidakaan lukea, mutta bufferia, johon se puskettiin voidaan. Se on helppoa: debuggerista inspect päälle ja se on sisältö siinä. Yksinkertaista, mutta totta!


    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Aivosyöpää sairastava Olga Temonen TV:ssä - Viimeinen Perjantai-keskusteluohjelma ulos

      Näyttelijä-yrittäjä Olga Temonen sairastaa neljännen asteen glioomaa eli aivosyöpää, jota ei ole mahdollista leikata. Hä
      Maailman menoa
      91
      2900
    2. Pelotelkaa niin paljon kuin sielu sietää.

      Mutta ei mene perille asti. Miksi Venäjä hyökkäisi Suomeen? No, tottahan se tietenkin on jos Suomi joka ei ole edes soda
      Maailman menoa
      299
      1686
    3. Mikä saa ihmisen tekemään tällaista?

      Onko se huomatuksi tulemisen tarve tosiaan niin iso tarve, että nuoruuttaan ja tietämättömyyttään pilataan loppuelämä?
      Sinkut
      246
      1557
    4. Minkä merkkisellä

      Autolla kaivattusi ajaa? Mies jota kaipaan ajaa Mersulla.
      Ikävä
      87
      1391
    5. IL - VARUSMIEHIÄ lähetetään jatkossa NATO-tehtäviin ulkomaille!

      Suomen puolustuksen uudet linjaukset: Varusmiehiä suunnitellaan Nato-tehtäviin Puolustusministeri Antti Häkkänen esittel
      Maailman menoa
      402
      1374
    6. Nyt kun Pride on ohi 3.0

      Edelliset kaksi ketjua tuli täyteen. Pidetään siis edelleen tämä asia esillä. Raamattu opettaa johdonmukaisesti, että
      Luterilaisuus
      398
      1292
    7. Kiitos nainen

      Kuitenkin. Olet sitten ajanmerkkinä. Tuskin enää sinua näen ja huomasitko, että olit siinä viimeisen kerran samassa paik
      Tunteet
      2
      1079
    8. Esko Eerikäinen tatuoi kasvoihinsa rakkaan nimen - Kärkäs kommentti "Ritvasta" lävähti somessa

      Ohhoh! Esko Eerikäinen on ottanut uuden tatuoinnin. Kyseessä ei ole mikä tahansa kuva minne tahansa, vaan Eerikäisen tat
      Suomalaiset julkkikset
      38
      1037
    9. Hyväksytkö sinä sen että päättäjämme ei rakenna rauhaa Venäjän kanssa?

      Vielä kun sota ehkäpä voitaisiin välttää rauhanponnisteluilla niin millä verukkeella voidaan sanoa että on hyvä asia kun
      Maailman menoa
      329
      874
    10. Miksi Purra-graffiti ei nyt olekkaan naisvihaa?

      "Pohtikaapa reaktiota, jos vastaava graffiti olisi tehty Sanna Marinista", kysyy Tere Sammallahti. Helsingin Suvilahden
      Maailman menoa
      257
      855
    Aihe