Wolfff Temat założony przez niniejszego użytkownika |
[SFML] nieskończona pętla przy pobieraniu z pliku » 2018-08-14 14:39:48 Cześć, napotkałem problem którego nie jestem w stanie sam rozwiązać. Napisałem funkcję która pobiera numer, następnie otwiera plik i szuka danego numeru, po znalezieniu pobiera tekst poniżej aż nie pobierze znaku stop. Wszystko działa bardzo dobrze kiedy funkcja jest sama w sobie, jednak kiedy wrzuciłem ją do mojego większego projektu zaczęła się zapętlać w nieskończoność. Ogólnie program prosi użytkownika o wybranie paru opcji, następnie paru kolejnych i na podstawie tego tworzy ten numer który będzie szukany w pliku. Program więc polega na stanach bool, i kiedy ostatni z nich zostaje przełączony na true - moja funkcja czekająca w if może zacząć działać i przypisać linijki tekstu z pliku do zmiennych. Używając debuggera nie znalazłem niczego konkretnego co mogło by stworzyć ten problem, również wsadzanie tej funkcji w for(int i = 0; i<1; i++) żeby wykonała się tylko jeden raz nic nie dało. Czy może to być wina tego że znajduje się to wszystko w głównej pętli "dopóki okno jest otwarte"? Nie mam pomysłów. Kodu jest bardzo dużo i wiem że w mojej funkcji nie znajduje się żaden błąd (działa dobrze osobno), oraz pętle w głównym programie nie są niczym czego wcześniej nie robiłem. Wydaje mi się że może to być jakiś większy ogólny błąd w moim rozumowaniu, jestem całkiem nowy w używaniu SFML oraz stanów okien, jednak jeśli ktoś chciałby żebym wkleił ten cały kod to mogę to zrobić. Bardzo proszę o pomoc, dziękuję. |
|
pekfos |
» 2018-08-14 15:43:31 Bez kodu nie ma o czym rozmawiać. |
|
Wolfff Temat założony przez niniejszego użytkownika |
» 2018-08-14 16:06:11 Kod funckji pobierającej z pliku: void LookFor( std::string st, std::string & opt_o, std::string & opt_t, std::vector < std::string >& sto, std::vector < std::string >& result_o, std::vector < std::string >& result_t, std::vector < std::string >& stat_o, std::vector < std::string >& stat_t ) { std::fstream plik; plik.open( "story.txt", std::ios::in ); if( !plik.good() ) { std::cout << "nie udalo sie otworzyc pliku" << std::endl; } std::string tekst; std::string stopper; std::string starter; starter = st; stopper = "***"; bool lookin = true; while( lookin ) { std::getline( plik, tekst ); if( !( std::string::npos == tekst.find( starter ) ) ) { std::cout << "found it!" << std::endl; while( tekst != stopper ) { std::getline( plik, tekst ); if( tekst == "+++" ) { do { std::getline( plik, tekst ); sto.push_back( tekst ); std::cout << "gettin the story!" << std::endl; } while( tekst != "---" ); } if( tekst == "---" ) { std::getline( plik, tekst ); opt_o = tekst; std::getline( plik, tekst ); opt_t = tekst; } if( tekst == "#" ) { do { std::getline( plik, tekst ); result_o.push_back( tekst ); } while( tekst != "##" ); } if( tekst == "##" ) { do { std::getline( plik, tekst ); result_t.push_back( tekst ); } while( tekst != "$" ); } if( tekst == "$" ) { do { std::getline( plik, tekst ); stat_o.push_back( tekst ); } while( tekst != "$$" ); } if( tekst == "$$" ) { do { std::getline( plik, tekst ); stat_t.push_back( tekst ); } while( tekst != stopper ); } if( tekst == stopper ) { return; lookin = false; } } } else { std::cout << "ERROR couldn't find the story nb" << std::endl; } } plik.close(); sto.pop_back(); result_o.pop_back(); result_t.pop_back(); stat_o.pop_back(); stat_t.pop_back(); }
W głownej pętli znajduje się pare if oraz else if do stanów programu, wybranie opcji w jednym przestawia kolejny na true i tak pare razy. while( App.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { return( - 1 ); } if( event.type == sf::Event::KeyPressed ) { if( !loc_chosen ) { switch( event.key.code ) { case sf::Keyboard::Down: { if( location < 3 ) { location++; std::cout << location << std::endl; } break; } case sf::Keyboard::Up: { if( location > 0 ) { location--; std::cout << location << std::endl; } break; } case sf::Keyboard::Return: { st_number += std::to_string( location ); std::cout << "LOC NUMBER: " << st_number << std::endl; loc_chosen = true; break; } } } else if( loc_chosen && !job_chosen ) { std::cout << linia_loc[ location * 2 ] << std::endl; std::cout << linia_loc[( location * 2 ) + 1 ] << std::endl; switch( event.key.code ) { case sf::Keyboard::Up: choice = 0; break; case sf::Keyboard::Down: choice = 1; break; case sf::Keyboard::Return: st_number += std::to_string( choice ); st_number += std::to_string( 0 ); std::cout << "LOC + CHOICE NUMBER + RAND(0): " << st_number << std::endl; job_chosen = true; break; } } else if( job_chosen ) { if( event.key.code == sf::Keyboard::Return ) { stor++; } else if( stor > story_count ) { switch( event.key.code ) { case sf::Keyboard::Up: choice_1 = 0; break; case sf::Keyboard::Down: choice_1 = 1; break; } } } }
Następnie poza główną pętlą jest pare if do określenia które rzeczy mają zostać narysowane w oknie zależnie od stanu. Jednym z nich jest: if( job_chosen ) { LookFor( st_number, opt_one, opt_two, story, result_one, result_two, stats_one, stats_two ); }
W momencie dojścia do tego miejsca w programie w konsoli wypisuje non stop tekst z komendy std::cout z funkcji LookFor ("found it", "gettin the story") i nigdy już nie przestaje. Często też cały program się zawiesza. |
|
pekfos |
» 2018-08-14 17:06:05 Co znaczy 'zawiesza się'? LookFor() się nie kończy? Praktycznie każda pętla tam jest potencjalnie nieskończona, jeśli plik nie ma odpowiedniej zawartości. |
|
Wolfff Temat założony przez niniejszego użytkownika |
» 2018-08-14 17:09:58 Plik ma odpowiednią zawartość, jak już mówiłem - działa dokładnie jak powinien osobno. Działa również na tym samym pliku na którym był testowany. Jednak po wsadzeniu go do większego projektu gdy przechodziłem przez każdą linijkę krok po kroku z debugerrem pobiera każdą rzecz dobrze i w ostatniej linijce kiedy ma przestać ignoruje ją i wraca do pobierania od początku. Dlatego stwierdziłem że problem nie jest z tą funkcją tylko może z jej umiejscowieniem w większym programie(?). Tak, LookFor() się nie kończy, zamiast raz wyświetlić komunikat "found it" a potem 4x następną (bo są 4 linijki do pobrania po "+++") to wyświetla je non stop bez przerwy. |
|
pekfos |
» 2018-08-14 17:31:21 if( job_chosen ) { LookFor( st_number, opt_one, opt_two, story, result_one, result_two, stats_one, stats_two ); } |
Kontekst. |
|
Wolfff Temat założony przez niniejszego użytkownika |
» 2018-08-14 17:47:17 Mam dużo zmiennych typu string oraz kontenerów vector dla string. Chcę wyświetlić wczytane do nich linijki tekstu w odpowiednim czasie, również poza tym czasem nie da się ich pobrać ponieważ w trakcie poprzednich stanów ( !loc_chosen -> loc_chosen -> job_chosen) użytkownik dokonuje wyborów które zdeterminują z której części pliku tekstowego pobrać tekst (każdy wybór ma swój numer który po zatwierdzeniu zostaje dodany do zmiennej string, następnie tego numeru szuka LookFor(); ). Czyli gdy użytkownik przejdzie przez dwa ostatnie etapy mam pewność że wybory zostały dokonane oraz rzeczywisty numer do wyszukania znajduje się w mojej zmiennej. Wtedy też przechodzi program do job_chosen = true, co pozwala na rozpoczęcie szukania odpowiedniego tekstu w dokumencie.
|
|
pekfos |
» 2018-08-14 17:55:21 Lepszy byłby kod. Nie daje się pociętego kodu, jeśli nie ma ku temu dobrego powodu. Jakbyś wiedział co jest istotne, a co nie, to by cię tu teraz nie było. |
|
« 1 » 2 |