Nie potrafię doszukać się błędu w funkcji, którą napisałam, dlatego bardzo proszę o pomoc.

0

Witam.
Jest już późno... a ja nie mogę sobie poradzić. Mam 16 lat, w c++ piszę od niespełna miesiąca, dlatego proszę o wyrozumiałość. Rozwiązywałam właśnie zadania z tegorocznej matury, oczywiście podstawowej póki co i wszystko szło pięknie, jednak tylko do podpunktu c z zadania 6. Treść zadania jest pod tym adresem: http://pobieranie.dlastudenta.pl/matura/2012/informatyka/pp_a2.pdf.

A teraz do rzeczy. Poniżej zamieszczam funkcję stworzoną przeze mnie dla podpunktu c właśnie. Problem polega na tym, że funkcja ta zawsze zwraca: "Nikt nie wybrał pięciu kierunków studiów". Wynik powinien być inny i równy co najmniej 1 (bo dla pewności sama, ręcznie ustawiłam id jednej osoby na 5 kierunków). Bardzo proszę o pomoc w znalezieniu błędu. Absolutnie nie proszę o przerobionego gotowca, tylko o wskazówkę, zwykłe wskazanie błędu i ewentualnie podpowiedź możliwego sposobu rozwiązania. Mam nadzieję, że uszanujecie tę prośbę. Wyprzedzając: wiem, że można było zrobić to w excelu, jednak idąc za podpowiedzią profesora, uznałam to za dobre ćwiczenie dla c++.

void punkt_c()
	{
		ifstream zgloszenia("zgloszenia.txt"); // plik, z którego odczytam dane
		ifstream kandydaci("kandydaci.txt"); // drugi plik, z którego odczytam dane
		fstream dopis; // nazwa pliku, do którego dopiszę wyniki
		dopis.open("zadanie6.txt", ios::out|ios::app); // otwarcie pliku, do którego dopiszę wyniki
		
		dopis << "c)" << '\t' << "Osoby, które wybrały pięć kierunków:" << endl << endl;
		
		//zmienne ogólne
		string niewazne; 
		int i; int j=0;
		int suma=0; 
		
		// zmienne dla pliku 'zgloszenia'
		char id[4]; 
		
		// zmienne dla pliku 'kandydaci'
		int niepotrzebne;
		char drugieid[4]; 
		string imie, nazwisko;
		
		for (i=1;i<=2;i++) {zgloszenia >> niewazne;} // aby czytać 'zgloszenia' od drugiej linijki
		for (i=1;i<=8;i++) {kandydaci >> niewazne;} // aby czytać 'kandydaci' od drugiej linijki
		i=1; // przypisanie wartości potrzebnej w nastepnej czesci funkcji (patrz: while -> if)
		
		while (!kandydaci.eof())
			{
				kandydaci >> drugieid;
				kandydaci >> imie; 
				kandydaci >> nazwisko;
				// pozostałe wyrazy wiersza są nieważne, dlatego:
				kandydaci >> niepotrzebne; kandydaci >> niepotrzebne; kandydaci >> niepotrzebne; kandydaci >> niepotrzebne; 
				kandydaci >> niewazne;
				
				while (!zgloszenia.eof())
					{
						zgloszenia >> niewazne; // ta dana nie ma znaczenia
						zgloszenia >> id;
						
						if (strcmp(drugieid, id)==0) {suma++;} // jeśli id = drugieid to suma zostaje zwiekszona o 1
					}
				
				if (suma==5) // jesli po przejsciu pliku 'zgloszenia' suma wynosi 5, to znaczy, że ktos wybrał 5 kierunków
					{
						dopis << i << "." << '\t' << imie << " " << nazwisko << '\n'; // piszemy imie i nazwisko
						j=1; // ustalamy 1 dla j- blokujemy komunikat z następnego 'if'.
						i++;
					}
					
				suma=0;	// zerujemy sumę, żeby dla każdego kolejnego id liczyło powtórzenia od nowa
			}
		
		if (j==0) {dopis << "Nikt nie wybrał pięciu kierunków studiów.";}	
		dopis << '\n';
	}

Odnoszę wrażenie, że niewłaściwe jest porównanie zmiennej 'id' do zmiennej 'drugieid', jednak nie mam pojęcia, co w tym zapisie jest błędem, bo wykonując go na 2, czy tam 3 inne sposoby dalej było to samo, czyli jeden wielki błąd.

Z góry dziękuję za wszystko...
i przepraszam, jeśli coś w moim poście jest nie tak, ale pierwszy raz proszę na forum o pomoc (taka desperacja : d).

Dobrej nocy!

0

Przecież to zadanie jest ewidentnie z Accessa. Oczywiście da się to napisać w kilkanaście minut, ale w Accessie zajmie Ci to 3/4 minuty..

Formatuj Kod!

while (!kandydaci.eof())

To nie do końca dobrze zadziała..
Ja bym użył tutaj mapy i po sprawie..
Nio i jeżeli już chcesz do tego pisać program, to tutaj aż prosi się o obiektowe podejście do sprawy..

0
 
while (!kandydaci.eof()){
     while (!zgloszenia.eof()) {}
}

w takim wypadku plik "zgloszenia" odczytasz tylko raz a nie za każdym obrotem pętli wcześniejszej

0

@kopernik
W poprzednich podpunktach ta pętla działa, co świadczy o tym, że w pliku nie ma ukrytych znaków EOF i występuje on tylko na końcu pliku.
Oczywiście, że można zrobić to w Accesie... jednak pisałam, że nie chodzi mi o 'wykonanie zadania', tylko 'wykonanie zadania w c++'.

@pecet
Słuszna uwaga, dziękuję. Poprawiłam to więc, przed pętlami zamykając plik 'zgloszenia', by potem otwierać go przed pętlą dla zgłoszeń i tuż po niej, czyli przy każdym przejściu pierwszej pętli plik otwiera się, druga pętla przechodzi, a potem plik zamyka się.

Jednak mimo to, nadal otrzymuję ten sam, błędny wynik.

1

Skorzystaj z mapy..

void punkt_c(){
    std::ifstream kandydaci("kandydaci.txt");
    std::ifstream zgloszenia("zgloszenia.txt");
    std::string tmp,id,imie,nazwisko,plec,m,i,f,l;
    getline(kandydaci,tmp);//wczytujemy pierwszą linijkę
    std::map<std::string,int>kan;
    std::map<std::string,int>::iterator it;
    while(kandydaci>>id&&kandydaci>>imie&&kandydaci>>nazwisko&&kandydaci>>m&&kandydaci>>i&&kandydaci>>f&&kandydaci>>l&&kandydaci>>plec){
        kan.insert(std::pair<std::string,int>(id,0));
    }
    while(zgloszenia>>tmp&&zgloszenia>>id){
        kan[id]++;
    }
    for (it=kan.begin();it!=kan.end();it++){
        if((*it).second==5)
         std::cout<<(*it).first<<" => "<<(*it).second << "\n";
    }
    kandydaci.close();
    zgloszenia.close();
}

To jest brzydko napisane, ale działa. Nadal proponuje napisać to obiekowo, ale jeżeli nie znasz tego paradygmatu, to zobacz kod wyżej..

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