Badanie poszczególnych linijek z pliku

0

Witam, mam problem z moim programem. Całość polega na tym, że uzupełniam strukturę danymi, następnie przepisuje całość do pliku tekstowego (to mam gotowe). Później odczytuje ten plik i wypisuje określone dane, w tym przypadku nazwisko i miejsce urodzenia. Problem polega na tym, że moja funkcja działa tylko wtedy kiedy w danej linijce są tylko dwa słowa, dlatego zamiast "Miejsce urodzenia:" muszę wpisać "Urodzony:" a nazwa miasta, może składać się tylko z jednego słowa.

 
void fun_c (char *nazwapliku)
{
	char znak;
	string zmienna, dane;
	ifstream fin(nazwapliku);
	if (!fin)
		cout<<"plik nie zostal otwarty"<<endl;
	else
		{
			cout<<"\nc) Nazwiska i miejsca urodzenia wszystkich studentow:\n"<<endl;
			while (!fin.eof())
				{
					fin>>zmienna>>dane;
					if (zmienna=="Nazwisko:")
						cout<<dane<<endl;
					if (zmienna=="Urodzony:")
						cout<<dane<<"\n"<<endl;
				}
		}
	fin.close();
	fflush(stdin);
}

Zrobiłem to w ten sposób, ponieważ inna funkcja liczy średnią wieku wszystkich studentów, dlatego struktura pliku tekstowego, gdzie każda linijka zawiera po dwa słowa była dla mnie najwygodniejszą opcją:
user image

 
void fun_d (char *nazwapliku, int n)
{
	char znak;
	double iloraz, suma;
	string zmienna, dane;
	ifstream fin(nazwapliku);
	if (!fin)
		cout<<"plik nie zostal otwarty"<<endl;
	else
		{
			while (!fin.eof())
				{
					fin>>zmienna>>dane;
					if (zmienna=="Wiek:")
						suma+=atoi(dane.c_str());
				}
		}
	iloraz=suma/n;
	cout<<"d) Srednia wieku wszystkich studentow: "<<iloraz<<endl;
	fin.close();
	fflush(stdin);
}

Ma ktoś pomysł jak rozwiązać ten problem?

1

Użyj getline.

1

Najlepiej będzie jak każdą wartość w pliku będziesz przechowywać po znaku :. Będzie wtedy łatwiej parsować plik i wklejać wartości do odpowiednich pól struktury:

#include<iostream>
#include<string>
#include<vector>
#include<fstream>
using namespace std;

class studenci{
private:
	struct osoba{
		int numer;
		string imie;
		int wiek;
	};

	vector<osoba> osoby;

public:
	void odczytaj(const char* sciezka){
		fstream plik(sciezka, ios::in);
		if(plik.is_open()){
			string linijka = "";
			int licznik = 0;
			while(getline(plik, linijka)){
				linijka = linijka.substr(linijka.find_last_of(':') + 2);
				if(licznik == 0){
					this->osoby.push_back(osoba());
					this->osoby[this->osoby.size() - 1].numer = stoi(linijka);
				}
				else if(licznik == 1) this->osoby[this->osoby.size() - 1].imie = linijka;
				else if(licznik == 2) {
					this->osoby[this->osoby.size() - 1].wiek = stoi(linijka);
					licznik = 0;
					continue;
				}
				licznik++;
			}
		}
		else cout << "Blad otwarcia pliku." << endl;
	}

	void wypisz(){
		for(unsigned i = 0; i < this->osoby.size(); i++){
			cout << "Numer: " <<  this->osoby[i].numer << endl;
			cout << "Imie: " << this->osoby[i].imie << endl;
			cout << "Wiek: " << this->osoby[i].wiek << endl << endl;
		}
	}
};

int main(){	
	studenci std;
	std.odczytaj("baza.txt");
	std.wypisz();
	return 0;
}

Plik wygląda tak:

Student: 1
Imie: Grzegorz
Wiek: 18
Student: 2
Imie: Tomasz
Wiek: 23

Zapisywanie robisz w drugą stronę wpisując najpierw powiedzmy: "Student: ", a później wartość pola struktury. Plik w trybie append.

...gdzie każda linijka zawiera po dwa słowa była dla mnie najwygodniejszą opcją...

Nie musi tak być jeżeli zakończysz znakiem : każde wyrażenie przed zapisaniem wartości ze struktury. Przykład masz w odczycie z pliku.

PS: Pewnie da się lepiej zrobić parsowanie ale jest siódma rano :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1