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

Najlepsze wyniki - return value 3221226356

Ostatnio zmodyfikowano 2019-06-07 20:43
Autor Wiadomość
K1cek
Temat założony przez niniejszego użytkownika
Najlepsze wyniki - return value 3221226356
» 2019-06-07 14:39:06
Witam, napisałem prostą grę.

Mam problem z najlepszymi wynikami, funkcja która odpowiada za grę zwraca po jej zakończeniu wynik i nazwę gracza.
Zapisuję te dane do pliku scores.txt pod postacią:

Nazwa
123
Nazwa2
456

Teraz próbuję napisać funkcję, która wyciągnie te dane z pliku txt, posortuje i wyświetli 3 najlepsze wyniki. Funkcja tworzy 2 tablice,
do jednej wrzuca imiona do drugiej wyniki. Ogólnie na wyjściu wszystko jest niby dobrze ale program kończy z return value 3221226356.

Czy ma ktoś pomysł co może być nie tak albo jak inaczej zaimplementować te "najlepsze wyniki" ?


C/C++
#include <iostream>
#include <fstream>
#include <conio.h>
#include <string>
#include <sstream>

using namespace std;

void odczyt()
{
    fstream plik;
   
    plik.open( "dane.txt", ios::in );
   
    string linijka;
   
    if( plik.good() )
    {
        int licznik = 0;
       
        while( !plik.eof() )
        {
            getline( plik, linijka );
            licznik++;
        }
       
        plik.clear();
        plik.seekg( 0 );
       
        int rozmiar = licznik / 2;
        string gracze[ rozmiar ];
        int wyniki[ rozmiar ];
       
        while( !plik.eof() )
        {
            getline( plik, linijka );
           
            gracze[ x ] = linijka;
            cout << "gracze[" << x << "] = " << gracze[ x ] << endl;
           
            getline( plik, linijka );
           
            istringstream iss( linijka );
            iss >> wyniki[ x ];
            cout << "wyniki[" << x << "] = " << wyniki[ x ] << endl;
            x++;
           
           
        }
       
        plik.close();
    }
    else
    {
        cout << "Error! Nie udalo się otworzyc pliku!" << endl;
    }
   
}
int main()
{
   
    odczyt();
   
    return 0;
}
P-174764
nanoant20
» 2019-06-07 15:24:22
gracze[ x ] = linijka;
x - nieznane
piszesz, że zapisujesz do scores.txt a otwierasz dane.txt
P-174765
pekfos
» 2019-06-07 15:27:15
C/C++
int rozmiar = licznik / 2;
string gracze[ rozmiar ];
int wyniki[ rozmiar ];
Tak się nie tworzy tablic w C++.

C/C++
while( !plik.eof() )
Tak się nie przechodzi po pliku w tej sytuacji. Wiesz dokładnie ile danych chcesz odczytać i ani trochę więcej. Jeśli wystąpi błąd odczytu, nie odczytasz niczego więcej, tym samym nigdy nie przerwiesz pętli i będziesz jechać po pamięci tak długo aż program się wysypie.

Wczytuj dane w jednej pętli do pierwszego błędu odczytu, wczytuj do dynamicznie rozszerzalnej tablicy i oddaj sobie przysługę i trzymaj dane w jednej tablicy, a nie w dwóch.
» Kurs C++ » Poziom 5Struktury lekcja
» Kurs C++ » Poziom 5Kontener std::vector<> lekcja
P-174766
K1cek
Temat założony przez niniejszego użytkownika
» 2019-06-07 16:23:35
Rozumiem, że chodziło o coś w tym stylu ? A jeżeli jest to w miarę dobrze to jak teraz poruszać się po tych elementach i je posortować ?
Oczywiście nie chodzi o gotowe rozwiązanie, poprostu nie wiem jaka jest składnia by chociaż wypisać te elementy, to dla mnie nowy temat.

C/C++
#include <iostream>
#include <fstream>
#include <conio.h>
#include <string>
#include <sstream>
#include <iterator>
#include <vector>

using namespace std;

struct DANE
{
    string imiona;
    int wyniki;
};
void Sortowanie( vector < DANE > vect )
{
    if( vect.empty() )
    {
        cout << "\nBłąd, brak wartości.";
    }
   
    else
    {
        for( int count = 0; count < vect.size(); count++ )
        {
            for( int count1 = 1; count1 < vect.size() - 1; count1++ )
            {
                if( vect[ count1 - 1 ].wyniki < vect[ count1 ].wyniki )
                {
                    swap( vect[ count1 - 1 ], vect[ count1 ] );
                }
            }
        }
        for( int i = 0; i < vect.size(); i++ )
        {
            cout << "Imie - " << vect[ i ].imiona << "  WYNIK " << vect[ i ].wyniki << endl;
        }
       
    }
   
}

void odczyt()
{
   
    vector < DANE > mojWektor;
    DANE Wyniki;
   
    fstream plik;
   
    plik.open( "dane.txt", ios::in );
   
    string linijka;
    int helper;
    if( plik.good() )
    {
        while( !plik.eof() )
        {
            getline( plik, linijka );
            Wyniki.imiona = linijka;
            getline( plik, linijka );
            istringstream iss( linijka );
            iss >> Wyniki.wyniki;
           
            mojWektor.push_back( Wyniki );
        }
        Sortowanie( mojWektor );
        plik.close();
    }
    else
    {
       
        cout << "Error! Nie udalo otworzyc sie pliku!" << endl;
       
    }
   
}
int main()
{
   
    odczyt();
   
    return 0;
}
.
P-174767
pekfos
» 2019-06-07 16:29:44
Wszystkie odpowiedzi masz w dwóch lekcjach które podałem i w » Kurs C++ » Poziom 5Wprowadzenie do standardowych algorytmów lekcja.

C/C++
while( !plik.eof() )
Jeśli nie obsługujesz błędów, pętla ma się przerwać na pierwszym błędzie.
C/C++
while( !plik.fail() )
Dopóki nie zaczniesz obsługiwać błędów, możesz zapomnieć o używaniu eof().
P-174768
K1cek
Temat założony przez niniejszego użytkownika
» 2019-06-07 17:19:27
Dziękuje za odpowiedź pekfos. Udało mi się stworzyć coś takiego, działa i się kompiluje bez błędu.
Gdyby ktoś jednak zauważył, że coś można było zrobić lepiej proszę o komentarz.

C/C++
#include <iostream>
#include <fstream>
#include <conio.h>
#include <string>
#include <sstream>
#include <iterator>
#include <vector>

using namespace std;

struct DANE
{
    string imiona;
    int wyniki;
};
void Sortowanie( vector < DANE > vect )
{
    if( vect.empty() )
    {
        cout << "\nBłąd, brak wartości.";
    }
   
    else
    {
        for( int count = 0; count < vect.size(); count++ )
        {
            for( int count1 = 1; count1 < vect.size() - 1; count1++ )
            {
                if( vect[ count1 - 1 ].wyniki < vect[ count1 ].wyniki )
                {
                    swap( vect[ count1 - 1 ], vect[ count1 ] );
                }
            }
        }
        for( int i = 0; i < vect.size(); i++ )
        {
            cout << "Imie - " << vect[ i ].imiona << "WYNIK " << vect[ i ].wyniki << endl;
        }
       
    }
   
}

void odczyt()
{
   
    vector < DANE > mojWektor;
    DANE Wyniki;
   
    fstream plik;
   
    plik.open( "dane.txt", ios::in );
   
    string linijka;
    int helper;
    if( plik.good() )
    {
        while( !plik.fail() )
        {
            getline( plik, linijka );
            Wyniki.imiona = linijka;
            getline( plik, linijka );
            istringstream iss( linijka );
            iss >> Wyniki.wyniki;
           
            mojWektor.push_back( Wyniki );
        }
        Sortowanie( mojWektor );
        plik.close();
    }
    else
    {
       
        cout << "Error! Nie udalo otworzyc sie pliku!" << endl;
       
    }
   
}
int main()
{
   
    odczyt();
   
    return 0;
}
P-174770
K1cek
Temat założony przez niniejszego użytkownika
» 2019-06-07 17:27:01
P-174771
pekfos
» 2019-06-07 17:41:51
C/C++
void Sortowanie( vector < DANE > vect )
Przekazuj kontener przez referencję, by uniknąć niepotrzebnego kopiowania i faktycznie mieć posortowane dane po wywołaniu tej funkcji.

C/C++
for( int count = 0; count < vect.size(); count++ )
{
    for( int count1 = 1; count1 < vect.size() - 1; count1++ )
    {
        if( vect[ count1 - 1 ].wyniki < vect[ count1 ].wyniki )
        {
            swap( vect[ count1 - 1 ], vect[ count1 ] );
        }
    }
}
Gratuluję napisania sortowania - teraz możesz śmiało korzystać z gotowców. std::sort() działa szybciej niż twoje O(n2) i krócej jest napisać kryterium sortowania i użyć gotowego algorytmu, niż pisać za każdym razem proste sortowanie od zera.

C/C++
while( !plik.fail() )
{
    getline( plik, linijka );
    Wyniki.imiona = linijka;
    getline( plik, linijka );
    istringstream iss( linijka );
    iss >> Wyniki.wyniki;
   
    mojWektor.push_back( Wyniki );
}
To nie jest technicznie rzecz biorąc najlepsze rozwiązanie. Tak na prawdę chcesz wczytać dane, potem sprawdzić błąd i na koniec dodać element do kontenera. Wczytując do pierwszego błędu raczej nie chcesz uwzględniać błędnego wpisu. Użycie istringstream jest też niebardzawe, lepiej od razu wczytywać int (ze wszystkimi konsekwencjami » Kurs C++ / FAQstd::getline() mi nie działa! pytanie/odpowiedź):
C/C++
while( true )
{
    getline( plik, Wyniki.imiona );
    plik >> Wyniki.wyniki;
    if( plik.fail() )
         break;
   
    plik.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
    mojWektor.push_back( Wyniki );
}
Zanim pomyślisz, że eof() mogłoby być w warunku pętli, to przypominam, że miałeś zapomnieć o eof(). eof() w tym wypadku byłoby zawsze prawdziwe, bo koniec pliku jest wykrywany gdy jest przyczyną błędu odczytu, więc przerwanie pętli na błędzie to wyłapie. Korzystając z tego, że std::getline() zwraca swój pierwszy argument, a strumień jest konwertowalny na wartość logiczną o wartości !fail(), można ten zapis skrócić do takiej pętli:
C/C++
while( getline( plik, Wyniki.imiona ) >> Wyniki.wyniki )
{
    plik.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
    mojWektor.push_back( Wyniki );
}
P-174772
« 1 » 2
  Strona 1 z 2 Następna strona