Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Tiedoston lukemisen toteutus

FrozenFire [13.08.2006 09:35:40]

#

Eli tahtona olisi lukea tiedosto muistiin. Aina rivi kerrallaan sana luokan olioihin.
Oliolla on 3 string tyypin muuttujaa kys1 kys2 kys3 ja toiset kolme, vast1 vast2 vast3.

"kysymykset" ja "vastaukset" erotellaan keskenään pilkulla, ja toisistaan tabulaattorilla. Esimerkki tiedoston sisällöstä:

menestys	success
menestyksekäs	successful
olipa kerran	once upon time
mummi, mummo	granny

Eli olipa kerran tai once upon time ovat vain yksi sana, kun taas mummi, mummo ovat eri sanoja. Rivin ensimmäiset sanat ovat kysX muuttujia ja tab:in jälkeiset vastX muuttujia.

Tiedosto luettaisiin siis sana luokan olio taulukkoon. Ja ongelmana on erottaa kys. vast toisistaan. Sanavälit jätetään huomiotta, joten joku getline() voisi toimia. Mutta saako siihen esim. useita lopetus merkkejä?

Eli miten tiedoston saisi luettua. Pitäisikö tiedoston "muotoa"(välimerkkejä tms.) vaihtaa?

Jos ei tullut jo selväksi niin ohjelmasta tarkoitus tulla sanojen tenttaaja.

Metabolix [16.08.2006 02:27:45]

#

Käytä getline-funktiota rivin lukemiseen (string-muuttujaan) ja pätki se string-luokan find_first_of- ja substr-funktioiden avulla.

FrozenFire [16.08.2006 22:30:46]

#

int tiedostonLuku(ifstream &rtiedosto,sana * pSana, int rivit)
{
	if(!rtiedosto.is_open())
	{
		cout<<"virhe tiedoston luku ei saanut tiedostoa!\n";
		return 1;
	}
	int rivi = 0;								//pitää lukua monenteen olioon ollaan tallentamassa
	int mones = 1;								//monesko sana menossa
	int tyyppi = 1;								//1=kys 2=vast
	int uusi = 1;								//jatketaan vanhaa 0, uusi sana 1
	char syote;
	string sana;
	while (!rtiedosto.eof())
	{
	if (rivi = rivit) {break;}					//Jos taulukko loppuu kesken, keskeytetään
	rtiedosto.get(syote);
		if(!(syote==','||syote=='\t'||syote=='\n')) //jos ei ohjaus merkkejä niin lisätään luettu
		{											//merkki sanan jatkoksi
			if (uusi) {sana = syote; uusi=0;}
			else {sana += syote;}
		}
		if (syote==','||syote=='\t'||syote=='\n')
		{
			if (mones <1 || mones >2)		//virheen tarkistus
			{
				cout<<"virhe tiedoston luvussa. muuttuja \"mones\" \n";
				return 1;
			}
			if (tyyppi<1 || tyyppi>2)
			{
				cout<<"virhe tiedoston luvussa. muuttuja \"tyyppi\" \n";
				return 1;
			}
			if (mones==1 && tyyppi==1)
			{
				pSana[rivi].tallennaKys1(sana);
				uusi = 1;
			}
			if (mones==2 && tyyppi==1)
			{
				pSana[rivi].tallennaKys2(sana);
				uusi = 1;
			}
			if (mones==1 && tyyppi==2)
			{
				pSana[rivi].tallennaVast1(sana);
				uusi = 1;
			}
			if (mones==2 && tyyppi==2)
			{
				pSana[rivi].tallennaVast2(sana);
				uusi = 1;
			}

			mones++;
		}
		if (syote=='\t')
		{
		tyyppi++;
		mones=1;
		}
		if (syote=='\n')
		{
			mones=1;
			tyyppi=1;
			rivi++;
		}
	return 0;
	}


}

Tuollasen luku funktion olen saanut rustattua. Eli luetaan tiedostoa merkki kerrallaan. Halutun merkin sattuessa kohdalle tehdään haluttu toiminto. Eli tallennetaan sana muuttujaan ja vaihdetaan muuttujaa. Se ei ole vielä valmis, tallentaa näemmä tyhjää.

Mitä mieltä olette, onkohan tehokas yms. Ja jos löydätte vian kertokaa ihmeessä. Muitakin parannus ehdotuksia otetaan vastaan.

Metabolix: Tuo kuullostaa hienolta, Mutta oma funktio oli jo niin pitkällä teossa, että jatkoin tuon tekoa.

FrozenFire [17.08.2006 07:47:51]

#

Jooh... parikin mokaa tuolla oli.Viiminen Return 0; oli eksyny väärään paikkaan. Mutta funktion katkasi jo

if (rivi = rivit) {break;}

Ei ollu ensimmäinen kerta ku vertauilu muuttui sijoituksesksi. No tuota saa silti kommentoida.

edit: jatkoa

Pidän funktiosta koska tuohon on verraten helppo lisätä uusia "muotoilu merkkejä" tms. Tuota pitää vielä kehittää eteenpäin. Ainakin jonkun tarkistuksen tupla merkeille aion tehdä.

Mutta nyt se toimii ja enää pitäs tehdä ainakin funktio joka kyselee sanoja satunnaisessa järjestyksessä.

Ps. On muuten monimutkaisin funktio jonka olen ohjelmoinut. ;)

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta