Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML] nieskończona pętla przy pobieraniu z pliku

Ostatnio zmodyfikowano 2018-08-14 23:55
Autor Wiadomość
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ę.
P-172095
pekfos
» 2018-08-14 15:43:31
Bez kodu nie ma o czym rozmawiać.
P-172096
Wolfff
Temat założony przez niniejszego użytkownika
» 2018-08-14 16:06:11
Kod funckji pobierającej z pliku:
C/C++
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(); //usuwa ostatni element (w tym wypadku pobrane niepotrzebnie "---")
    result_o.pop_back(); // usuwa "##"
    result_t.pop_back(); // usuwa numer nastepnego
    stat_o.pop_back(); // usuwa "$$"
    stat_t.pop_back(); // usuwa "***"
}

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.
 
C/C++
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:
C/C++
if( job_chosen )
{
    LookFor( st_number, opt_one, opt_two, story, result_one, result_two, stats_one, stats_two ); // <- zawiesza program
}

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.
P-172097
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.
P-172098
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.
P-172099
pekfos
» 2018-08-14 17:31:21
C/C++
if( job_chosen )
{
    LookFor( st_number, opt_one, opt_two, story, result_one, result_two, stats_one, stats_two ); // <- zawiesza program
}
Kontekst.
P-172100
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.
P-172101
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.
P-172102
« 1 » 2
  Strona 1 z 2 Następna strona