Tiedostoa luetaan rivi kerrallaan.
char get_string(char *entry, char *answer, char *filename) { string rivi; int paikka: ifstream fi( filename ); while( !fi.eof()) { getline(fi,rivi); // skip comment line if (rivi[0] == ':') continue; // strip douple ' ' // Check if this is what we locking for paikka = rivi.find(entry); if (paikka != string::npos) { } return 0; } }
Kohdat strip douple' ' ja tuon entryn tarkistus
tarvitsisi toteuttaa C++ ja mahdollisesti STL:ää käyttämällä minulla kuitenkin meni sormi suuhun.
Luettavan tiedoston sisältö on muotoa:
ETSITTÄVÄ_AVAIN etsittävä arvo
ongelmaksi muodostui että avaimen ja arvon välissä on epämääräinen määrä välilyöntejä ja arvo voi sisältää välilyönnin.
Katsotaanpa. Tahtosi on siis löytää tekstitiedostosta avaimia ja niiden arvoja, siten, että avaimset ja arvot ovat kummatkin omilla riveillänsä ja kommentoinnit ovat vain omillansa ja että kommentit aina alkavat kaksoispisteellä?
No ei nyt millään pahalla, mutta oma koodisi on vähän hakoteillä ja ilmeisesti siitä puuttuukin osa, mutta ei se mitään :) (joo ja mikäköhän tuo char get_string(char *entry, char *answer, char *filename) on.. funktio? hassu tyyppi, char.)
Mutta jos haluat jatkaa valitsemellais tielläin, niin olettaen, että avaimen nimi on todellakin ilman välilyöntejä, niiiin sen saa helposti löydettyä tahi luettua näin:
fi.getline(avain, 200, ' ');
Jossa alkuna fi on ifstream, avain on muuttuja johon tallennetaan (esim char-taulukko), 200 on merkkimäärä joka tallennetaan (joten kunhan avain ei ole yli 200 merkkiä pitkä..) ja tuo vika parametri, ' ', on merkki, johon saavuttaessa lukeminen lopetetaan, eli oikeasti ei suinkaan lueta 200 merkkiä vaan ensimmäiseen välilyöntiin asti. :)
tai sama onnistuu tätenkin (saattaa tarvita #include <iostream>:n lisäämisen):
fi >> avain;
Jossa taas käytetään ovelasti tietovirtoja avuksi. Tuokin lukee ensimmäiseen välilyöntiin TAI rivinvaihtoon.. Tai tiedoston loppuun.
Ja kun tuo ollaan luettu, niin voidaan oikein ovelasti tehdä vaikkapa näin (tähän on montakin tapaa):
fi >> ws;
Jossa ws tarkoittaa whitespacea, eli tiedostoa luetaan välilyöntien ja rivinvaihtojen yli seuraavan "varsinaisen" datan alkuun.
Vaihtoehtoinen tapa voisi olla esimerkiksi näin:
while (fi.peek() != ' ') //peek() on sitä, että katsotaan seuraava merkki tiedostosta, mutta ei varsinaisesti lueta sitä getline(rivi, 1, 'z')
Eli, tässä vaiheessa ollaan sitten pääsemässä arvon lukemiseen. Ja se taas luetaan erittäin helposti täten:
fi.getline(arvo, 200, '\r\n') // eli luetaan 200 merkkiä tai kunnes tulee rivinvaihto. Täten välilyöntien pitäisi tulla mukaan
Jaaha, toivottavasti ei taas pelkkää paskaa tullut, mutta jos tuli, niin huomauttakoot joku :>
Ja tuon kaiken jälkeen tietenkin tallennat luetun avaimen ja arvon taulukkoon. Sen varmaan osaat itsekin :)
EDIT: ja vielä se, että tähän voisi soveltaa STL:n vektoreita toki ja ehkä muutamaa muutakin juttua. Vektorit varsinkin voisivat olla ihan hyödyllisiä jos avaimien ja niiden arvojen määrää ei tiedetä..
Manipulaattori ws on ratkaisusi. Siihen lukemalla saat virrasta pois kaiken tyhjän ennen seuraavaa sanaa.
std::string avain, arvo; // Jatketaan niin kauan, kuin tiedostossa on jotakin vielä senkin jälkeen, kun on otettu tyhjät pois... while (!(tiedosto >> std::ws).eof()) { // Luetaan sana ja otetaan tyhjät perästä pois tiedosto >> avain >> std::ws; getline(tiedosto, arvo); // Ja sitten voit tarkistaa kommenttirivit (avain[0]) (# olisi muuten standardimpi kommenttimerkki) }
Tzaeru, et voi laittaa \r:ää ja \n:ää samaan merkkiin, aivan kuten et voi laittaa a:ta ja b:tä samaan merkkiin. Noista ensimmäistä edes käytetä kuin Windowsissa ja Macissa, joten se on siltäkin kannalta huono ratkaisu.
Niin ja mikähän se "strip douple" yrittää olla?
Anteeksi :( Oletin tosin vain, että kyseisellä henkilöllä olisi windows kun ei asiasta erikseen maininnut.. (en siksi, että olisi mitään faktatietoa, vaan ihan kokemuksesta)
Kiitos neuvoista...
char get_string... on/oli funktion nimi...
Mutta perimmäinen tarkoitushan on että funktio etsii annetun avaimen arvon annetusta tiedostosta ja palauttaa avaimen arvon (arvo voi olla numero taikka sanoja) sen vuoksi en haluasi laittaa arvoja vektoriin.
strip double oli tarkoitus olla ylimääräisten välilyöntien poisto... (tätähän ei tosiasiassa tarvita :o )
niin ja Windows ympäristö on käytössä.
Mutta näillä ohjeillahan tuon jo saakin toimimaan (toivottavasti)
Tzaeru kirjoitti:
Anteeksi :( Oletin tosin vain, että kyseisellä henkilöllä olisi windows kun ei asiasta erikseen maininnut.. (en siksi, että olisi mitään faktatietoa, vaan ihan kokemuksesta)
Standardivirtojen tapauksessa asiasta ei edes tarvitse välittää, jos tiedosto on avattu tekstimoodissa. Kirjasto hoitaa "\r\n <-> \n" muunnoksen aina tarvittaessa. Aina pitää siis käyttää "\n"-merkintää.
Aihe on jo aika vanha, joten et voi enää vastata siihen.