C++:lla luokka-inputtien lukeminen tiedostosta

Olen tehnyt luokan

struct foo{
int var1;
int var2;
string var3;
double var4;
string var5;
};


Tiedostossa input.in on annettu syöttötiedot n:lle "datapisteelle". Yksi "datapiste" sisältää datan attribuuteille var1, var2, var3 ja var5, jokainen omalla rivillään. Inputit attibuutille var 4 arvon itse erikseen. Tahtoisin nyt lukea tuosta tiedostosta syötteet muuttuja-attribuuteille var1, var2, var3 ja var5 n-kokoiseen taulukkomuuttujaan, jonka elementit ovat tyyppiä foo. Luonnollisesti en haluaisi pitää itse kirjaa kuinka monta datapistettä tiedostossa on (eli lukumäärästä n) vaan ohjelman tulisi selvittää tämä. Kuinkakohan tämä datan lukeminen oikein kannattaisi tehdä?
5562
Äänestä

Muut lukivat myös

Vastaukset 5

Vanhimmat

Voit käydä tiedoston etukäteen läpi ja laskea rivit / rivinvaihdot. Jakamalla sen neljällä saat sitten elementtien määrän, toinen tapa on käyttää vektoria tallennukseen, lukea neljä riviä temp-foohon ja aina onnistuneen luvun jälkeen syöttää uusi elementti vektoriin.

Äänestä
  • No joo, noin ajattelin sen itsekin menevän ideatasolla. En vain tiedä kuinka toteuttaa tuo käytännössä. Ilmeisesti pitäisi käyttää noita C :n stream-juttuja, mutta omassa C raamattussani noista ei puhuta yhtään mitään ja googlella hakiessani löysin korkeintaan esimerkkejä, joissa luetaan yksi kirjain tiedostosta ja tulostetaan se näytölle. Ensimmäinen ongelma on siis rivien lukumäärän laskeminen ja toinen tuo sijoitusoperaatio streamista. Minulle on epäselvää, että mistä ohjelma tietää, että mitä kohtaa (riviä) tiedostosta kulloinkin luetaan ja mikä on hyvä/oikea tapa lukea streamia. C:llä, joka on itselleni vähän tutumpi, lukuhan menee fscanf:llä riveittäin.

    Äänestä

  • Heikka H. kirjoitti:

    No joo, noin ajattelin sen itsekin menevän ideatasolla. En vain tiedä kuinka toteuttaa tuo käytännössä. Ilmeisesti pitäisi käyttää noita C :n stream-juttuja, mutta omassa C raamattussani noista ei puhuta yhtään mitään ja googlella hakiessani löysin korkeintaan esimerkkejä, joissa luetaan yksi kirjain tiedostosta ja tulostetaan se näytölle. Ensimmäinen ongelma on siis rivien lukumäärän laskeminen ja toinen tuo sijoitusoperaatio streamista. Minulle on epäselvää, että mistä ohjelma tietää, että mitä kohtaa (riviä) tiedostosta kulloinkin luetaan ja mikä on hyvä/oikea tapa lukea streamia. C:llä, joka on itselleni vähän tutumpi, lukuhan menee fscanf:llä riveittäin.

    tässä lyhyt esimerkki tiedoston lukemisesta rivi kerrallaan:

    fstream fs;
    fs.open("in.txt", ios::in);

    char buffer[256];
    int c = 0;
    while (!fs.feof()) {
    /* luetaan buffer-tauluun merkkejä kunnes on luettu 256-1 merkkiä tai tullaan vastaan rivinvaihtomerkkiin '\n' */
    fs.getline(buffer, 256, '\n');
    c ;
    }

    Tuossa samalla kasvatetaan laskuria jokaisella rivinluvulla, eli tuo laskisi myös tiedoston rivit.

    fs.seekg(x) asettaa streamin lukuposition, jos sitten haluaa kelata takaisin tiedoston alkuun.

    Jos buffer täyttyy, niin fs.fail() palauttaa true-arvon. Yleensäkin tuo kannattaa tarkistaa jos erikoisia ongelmia ilmenee, fs.clear() nollaa tilan jonka jälkeen lukua voidaan jatkaa sillä fail on ns. non-fatal error, fatal error ilmenee jos fs.bad() palauttaa toden arvon.

    Äänestä

  • Vasenjalkainen kirjoitti:

    tässä lyhyt esimerkki tiedoston lukemisesta rivi kerrallaan:

    fstream fs;
    fs.open("in.txt", ios::in);

    char buffer[256];
    int c = 0;
    while (!fs.feof()) {
    /* luetaan buffer-tauluun merkkejä kunnes on luettu 256-1 merkkiä tai tullaan vastaan rivinvaihtomerkkiin '\n' */
    fs.getline(buffer, 256, '\n');
    c ;
    }

    Tuossa samalla kasvatetaan laskuria jokaisella rivinluvulla, eli tuo laskisi myös tiedoston rivit.

    fs.seekg(x) asettaa streamin lukuposition, jos sitten haluaa kelata takaisin tiedoston alkuun.

    Jos buffer täyttyy, niin fs.fail() palauttaa true-arvon. Yleensäkin tuo kannattaa tarkistaa jos erikoisia ongelmia ilmenee, fs.clear() nollaa tilan jonka jälkeen lukua voidaan jatkaa sillä fail on ns. non-fatal error, fatal error ilmenee jos fs.bad() palauttaa toden arvon.

    Miten kyseiseen koodipätkään lisätään lause joka
    etsii jokaiselta riviltä esim. 01020304050607080910
    01020304050607080910

    kolme eniten toistensa kanssa esiintynyttä numeroa??

    (toivottavasti asian en liian vaikeasti ilmaissut)

    Äänestä

>Olen tehnyt luokan

Kyseessä ei ole luokka vaan pelkkä struktuuri joka onnistuu ihan perinteisellä C:llä. Ei siis tarvitse C :aa.

>...taulukkomuuttujaan, jonka elementit ovat tyyppiä foo
>...vaan ohjelman tulisi selvittää tämä.

Sehän selviää automaattisesti kun taulukon indeksistä täytyy pitää kirjaa joka tapauksessa.

Äänestä

Kommentoi aloitusta


Heikka H kirjoitti:

Olen tehnyt luokan

struct foo{
int var1;
int var2;
string var3;
double var4;
string var5;
};


Tiedostossa input.in on annettu syöttötiedot n:lle "datapisteelle". Yksi "datapiste" sisältää datan attribuuteille var1, var2, var3 ja var5, jokainen omalla rivillään. Inputit attibuutille var 4 arvon itse erikseen. Tahtoisin nyt lukea tuosta tiedostosta syötteet muuttuja-attribuuteille var1, var2, var3 ja var5 n-kokoiseen taulukkomuuttujaan, jonka elementit ovat tyyppiä foo. Luonnollisesti en haluaisi pitää itse kirjaa kuinka monta datapistettä tiedostossa on (eli lukumäärästä n) vaan ohjelman tulisi selvittää tämä. Kuinkakohan tämä datan lukeminen oikein kannattaisi tehdä?

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu