Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!

Ogłoszenie

Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.

#1  2012-03-03 16:03:00

  lubiekoty1 - Użytkownik

lubiekoty1
Użytkownik
Zarejestrowany: 2012-02-09

[SOLVED] C++ Problem z poprawnym odczytem informacji z pliku.

Witam,
I tym razem przybywam na forum z prośbą o udzielenie mi pomocy.
Część, która przysparza mi problemu polega na odczytaniu informacji (imię , nazwisko , oceny z 3 przedmiotów szkolnych) dla 10 osób z pliku tekstowego ,,uczniowie.txt"

Kod:

 Problem: jedynie informacje o ostatniej osobie wpisanej w plik tekstowy zostają przekazane do kompilatora / zamiast wszystkich 10 osób.

Kod:

#include <iostream>
#include <cstdlib>
#include <string>
#include <fstream>

using namespace std;

class Dane_Ucznia
{
    private:
        string imie , nazwisko;
        int matematyka , fizyka , informatyka;

    public:
        Dane_Ucznia (string imie_, string nazwisko_, int matematyka_, int fizyka_, int informatyka_);
        void Male_Intro();
        void Srednia_Ocen_Ucznia();
        void Srednia_Ocen_Uczniow();
        void Zapisz_Do_Pliku();
        void Wczytaj_Z_Pliku();
        void Wypisz_Dane();
};

    Dane_Ucznia :: Dane_Ucznia (string imie_, string nazwisko_, int matematyka_, int fizyka_, int informatyka_): //Konstruktor
            imie(imie_), nazwisko(nazwisko_), matematyka(matematyka_), fizyka(fizyka_),informatyka(informatyka_){}

    void Dane_Ucznia :: Male_Intro()

        {
            cout <<"****************************************************************************" <<endl;
            cout <<"**   PROGRAM #1 - Liczenie sredniej z trzech przedmiotow dla 10 uczniow   **" <<endl;
            cout <<"****************************************************************************" <<endl;
        }

    void Dane_Ucznia :: Wczytaj_Z_Pliku()
            {


               Dane_Ucznia * Tablica_Uczniow[10]; // Tworzenie tablicy

               ifstream Plik_Tekstowy("c://uczniowie.txt");

               if (Plik_Tekstowy.is_open())
                {
                    while (Plik_Tekstowy.good())//do konca pliku
                    {

                    for (int i=1 ; i <= 10; i++)
                        {
                            Plik_Tekstowy >> imie;
                            Plik_Tekstowy >> nazwisko;
                            Plik_Tekstowy >> matematyka;
                            Plik_Tekstowy >> fizyka;
                            Plik_Tekstowy >> informatyka;
                            Tablica_Uczniow[i]= new Dane_Ucznia(imie, nazwisko, matematyka, fizyka, informatyka);
                        }
                    }
                }
            }

    void Dane_Ucznia :: Wypisz_Dane()
        {
    Dane_Ucznia * Tablica_Uczniow[10]; // Tworzenie tablicy

            for (int i= 0; i  < 10 ; i++)

                {
                    cout <<imie        <<endl;
                    cout <<nazwisko    <<endl;
                    cout <<matematyka  <<endl;
                    cout <<fizyka      <<endl;
                    cout <<informatyka <<endl;
                }
        }

    void Dane_Ucznia :: Srednia_Ocen_Ucznia()
    {

    }

    void Dane_Ucznia :: Srednia_Ocen_Uczniow()
    {
        double Srednia;
        
        for (int i= 0; i  < 10 ; i++)
            {   cout <<""<<endl <<endl;
                Srednia = ((matematyka + fizyka + informatyka)/30);
                cout <<"SREDNIA OCEN DLA CALEJ KLASY WYNOSI = " << Srednia;
            }
    }

    void Dane_Ucznia :: Zapisz_Do_Pliku()
    {

    }

int main ()
{
    Dane_Ucznia jeden ("","",0,0,0);
    jeden.Male_Intro();
    jeden.Wczytaj_Z_Pliku();
    jeden.Wypisz_Dane();
   /* jeden.Srednia_Ocen_Uczniow();*/
    system("PAUSE");
    return 0;
}

Dodatkowe informacje:
* Informacje pobierane są z pliku tekstowego - uczniowie.txt
* Informacje odczytywane są w postaci słowo za słowem (Oddzielone miedzy sobą spacja)
Zawartość pliku uczniowie.txt:

Kod:

Jan kowalski 3 2 1 Jan kowalski 3 2 1 Jan kowalski 3 2 1 Jan kowalski 3 2 1 Jan kowalski 3 2 1 Jan kowalski 3 2 1 Jan kowalski 3 2 1 Jan kowalski 3 2 1 Jan kowalski 3 2 1 Marcin kowalski 3 2 1

Serdecznie dziękuję za ewentualną pomoc.

Ostatnio edytowany przez lubiekoty1 (2012-03-03 19:19:08)

Offline

 

#2  2012-03-03 17:19:44

  Huk - Smoleńsk BULWA!

Huk
Smoleńsk BULWA!
Zarejestrowany: 2006-11-08

Re: [SOLVED] C++ Problem z poprawnym odczytem informacji z pliku.

Witam na formu.

Jako tako działający program wygląda tak:

Kod:

#include <iostream>
#include <cstdlib>
#include <string>
#include <fstream>

using namespace std;

class Dane_Ucznia
{
private:
    string imie , nazwisko;
    int matematyka , fizyka , informatyka;
    Dane_Ucznia * Tablica_Uczniow[10]; // Tworzenie tablicy

public:
    Dane_Ucznia (string imie_, string nazwisko_, int matematyka_, int fizyka_, int informatyka_);
    void Male_Intro();
    void Srednia_Ocen_Ucznia();
    void Srednia_Ocen_Uczniow();
    void Zapisz_Do_Pliku();
    void Wczytaj_Z_Pliku();
    void Wypisz_Dane();
};

Dane_Ucznia :: Dane_Ucznia (string imie_, string nazwisko_, int matematyka_, int fizyka_, int informatyka_): //Konstruktor
    imie(imie_), nazwisko(nazwisko_), matematyka(matematyka_), fizyka(fizyka_),informatyka(informatyka_){}

void Dane_Ucznia :: Male_Intro()

{
    cout <<"****************************************************************************" <<endl;
    cout <<"**   PROGRAM #1 - Liczenie sredniej z trzech przedmiotow dla 10 uczniow   **" <<endl;
    cout <<"****************************************************************************" <<endl;
}

void Dane_Ucznia :: Wczytaj_Z_Pliku()
{


    //Dane_Ucznia * Tablica_Uczniow[10]; // Tworzenie tablicy

    ifstream Plik_Tekstowy("c://uczniowie.txt");

    if (Plik_Tekstowy.is_open())
    {
        while (Plik_Tekstowy.good())//do konca pliku
        {
            for (int i=0 ; i < 10; ++i)
            {
                Plik_Tekstowy >> imie;
                Plik_Tekstowy >> nazwisko;
                Plik_Tekstowy >> matematyka;
                Plik_Tekstowy >> fizyka;
                Plik_Tekstowy >> informatyka;
                Tablica_Uczniow[i]= new Dane_Ucznia(imie, nazwisko, matematyka, fizyka, informatyka);
            }
        }
    }
}

void Dane_Ucznia :: Wypisz_Dane()
{
    //Dane_Ucznia * Tablica_Uczniow[10]; // Tworzenie tablicy

    for (int i= 0; i  < 10 ; i++)

    {
        cout <<Tablica_Uczniow[i]->imie        <<endl;
        cout <<Tablica_Uczniow[i]->nazwisko    <<endl;
        cout <<Tablica_Uczniow[i]->matematyka  <<endl;
        cout <<Tablica_Uczniow[i]->fizyka      <<endl;
        cout <<Tablica_Uczniow[i]->informatyka <<endl;
    }
}

void Dane_Ucznia :: Srednia_Ocen_Ucznia()
{

}

void Dane_Ucznia :: Srednia_Ocen_Uczniow()
{
    double Srednia;

    for (int i= 0; i  < 10 ; i++)
    {   cout <<""<<endl <<endl;
        Srednia = ((matematyka + fizyka + informatyka)/30);
        cout <<"SREDNIA OCEN DLA CALEJ KLASY WYNOSI = " << Srednia;
    }
}

void Dane_Ucznia :: Zapisz_Do_Pliku()
{

}

int main ()
{
    Dane_Ucznia jeden ("","",0,0,0);
    jeden.Male_Intro();
    jeden.Wczytaj_Z_Pliku();
    jeden.Wypisz_Dane();
    /* jeden.Srednia_Ocen_Uczniow();*/
    system("PAUSE");
    return 0;
}

Jednakże to jest nadal kod spaghetti :)

Błędy:

Po pierwsze, wielokrotnie tworzyłeś tablice uczniów, wewnątrz funkcji (zarówno na wczytywaniu jak i przy wypisywaniu, w tym drugim wypadku nawet nic z nią nie robiłeś, tylko sobie wisiała pusta ;] ), zamiast wyrzucić ją na zewnątrz do klasy - przez to wszystko się pierniczyło, bo na końcu zamiast wypisywać dane z zapełnionej tablicy, wypisywałeś ostatnie wczytane, które zawsze prezentowały ostatnią osobę.

Po drugie nie używaj konstrukcji w stylu:

Kod:

for(int i=1;i<=10;i++)

bo:

1. Nie jest to wydajne/
2. Gubisz przy tym pierwszy element tablicy (tab[1]=costam jest pierwsze, a tablice idą w końcu od zera do i-1).
3. Wychodzisz za zadeklarowaną wcześniej wielkość tablicy (tab[10]=costam to odniesienie do jedenastego elementu tablicy, jeżeli deklarujesz tab[10] to tablica ma wartości od 0 do 9), co skończy się wysypaniem programu, prędzej czy później.

Poprawnie powinno to wygadać tak:

Kod:

for(int i=0;i<10;++i)

Mniej porównań i komplikacji, a do tego preinkrementacja, która jest od postinkrementacji, szybsza (w pętlach w zasadzie chyba zawsze powinno się stosować preinkrementację, post jest stosowana znacznie rzadziej).

Po trzecie, stworzyłeś rekursywną klasę :D takiego dziwoląga widzę po raz pierwszy i powiedział bym wręcz że dziwne że to w ogóle działa :) . W przyszłości rozdziel sobie  takie rzeczy na np. klasę daneUcznia, oraz klasę kontenerową np uczniowie, zawierająca tablicę z danymi ucznia. W tej drugiej implementujesz takie metody jak wczytaj, zapisz czy wyświetl, a w tej pierwszej sam konstruktor powinien styknąć.

To tyle ode mnie, u mnie po modyfikacji program działa, ale wycieki pamięci zapewne nadal jakieś są, więc nie zdziw się jak się na innym kompie sypnie, najlepiej popraw tak jak napisałem, wtedy będzie od razu lepiej :)

Pozdro.

Offline

 

#3  2012-03-03 17:38:15

  lubiekoty1 - Użytkownik

lubiekoty1
Użytkownik
Zarejestrowany: 2012-02-09

Re: [SOLVED] C++ Problem z poprawnym odczytem informacji z pliku.

Bardzo dziękuje za pomoc :)


// Proszę o nie zamykanie tematu - Po drodze mogą wystąpić kolejne błędy z którymi nie będę mógł sobie poradzić.

Offline

 

#4  2012-03-03 18:36:42

  panjandrum - Użytkownik

panjandrum
Użytkownik
Skąd: Lublin/Kraków
Zarejestrowany: 2009-03-20

Re: [SOLVED] C++ Problem z poprawnym odczytem informacji z pliku.

@Huk, z tą większą szybkością preinkrementacji to trochę naciągane. Fakt, to jest dobry nawyk, ale dobry kompilator (jakim jest gcc) skompiluje do tego samego kodu, gdy nie przypisujemy nigdzie tej zmiennej. Sprawa jest chyba trochę inna z iteratorami.

Co do autora posta to bym się zapoznał na Twoim miejscu z STL-em i ogólnie zasadami jak poprawnie stosować klasy.


[url=https://github.com/panjandrum/obshutdown]obshutdown[/url] - Opedbox shutdown dialog

Offline

 

#5  2012-03-03 19:18:50

  lubiekoty1 - Użytkownik

lubiekoty1
Użytkownik
Zarejestrowany: 2012-02-09

Re: [SOLVED] C++ Problem z poprawnym odczytem informacji z pliku.

Z pewnością się zapoznam.

// Temat do zamknięcia program został dokończony bez żadnych problemów.

Offline

 

#6  2012-03-03 19:31:37

  azhag - Admin łajza

azhag
Admin łajza
Skąd: Warszawa
Zarejestrowany: 2005-11-15

Re: [SOLVED] C++ Problem z poprawnym odczytem informacji z pliku.

[quote=lubiekoty1]// Temat do zamknięcia program został dokończony bez żadnych problemów.[/quote]
Nie mamy zwyczaju zamykać wątków (o ile ktoś nie rozrabia).


Błogosławieni, którzy czynią FAQ.
[url=http://www.opencaching.pl]opencaching[/url] :: [url=http://dug.net.pl/sources.list]debian sources.list[/url] :: [url=http://www.linuxportal.pl/blogi/azhag/wpisy]coś jakby blog[/url] :: [url=http://dug.net.pl/]polski portal debiana[/url] :: linux user #403712

Offline

 

#7  2012-03-03 20:32:41

  Huk - Smoleńsk BULWA!

Huk
Smoleńsk BULWA!
Zarejestrowany: 2006-11-08

Re: [SOLVED] C++ Problem z poprawnym odczytem informacji z pliku.

@panjandrum:

Czy ja wiem? Na uczelni jeszcze kilka lat wstecz, chyba na poziomie assemblera było widać że dla post trzeba było (co zresztą logiczne) gdzieś tą wartość zapisać, zwiększyć  i na końcu przepisać, podczas gdy dla pre wystarczyło tylko zwiększyć, być może nowsze wersje GCC/G++ wykrywają czy ma to jakiś wpływ na logikę i potrafią odpowiednie "poprawić" za usera (albo po prostu kompy są na tyle szybkie że dla większości programów nie ma to aż takiego znaczenia), ale IMHO lepiej jawnie mu to zapisać i być pewnym że zadziała o te parę operacji szybciej :)

Do autora: tak jak @panjandrum pisze: STL, podstawy klas itd - jak początkujący to polecam Symfonię C++ Grębosza, IMHO jedna z najlepszych książek na początek. Polecam tez OD RAZU zaopatrzyć się w jakiś normalny edytor z uzupełnianiem kodu, debugerem i podobnymi pierdołami. QTCreator jest na tę chwilę chyba janbardziej uniwersalny, obsługuje zarówno czyste projekty C++, jak i QT, posiada graficzną nakładkę na GDB, jak i na Valgrinda. Polecam.

W ogóle, polecam zapoznać się z QT i wszelkie projekty w tym kminić, lepszego framweorka pod C++ raczej nie znajdziesz :] (wiem wiem, fanboy ze mnie - ale taka prawda).

Pozdro.

Offline

 

Stopka forum

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson
To nie jest tylko forum, to nasza mała ojczyzna ;-)

[ Generated in 0.010 seconds, 11 queries executed ]

Informacje debugowania

Time (s) Query
0.00011 SET CHARSET latin2
0.00004 SET NAMES latin2
0.00096 SELECT u.*, g.*, o.logged FROM punbb_users AS u INNER JOIN punbb_groups AS g ON u.group_id=g.g_id LEFT JOIN punbb_online AS o ON o.ident='18.118.144.199' WHERE u.id=1
0.00062 REPLACE INTO punbb_online (user_id, ident, logged) VALUES(1, '18.118.144.199', 1732374687)
0.00043 SELECT * FROM punbb_online WHERE logged<1732374387
0.00045 SELECT topic_id FROM punbb_posts WHERE id=196580
0.00004 SELECT id FROM punbb_posts WHERE topic_id=20821 ORDER BY posted
0.00062 SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, 0 FROM punbb_topics AS t INNER JOIN punbb_forums AS f ON f.id=t.forum_id LEFT JOIN punbb_forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id=20821 AND t.moved_to IS NULL
0.00005 SELECT search_for, replace_with FROM punbb_censoring
0.00326 SELECT u.email, u.title, u.url, u.location, u.use_avatar, u.signature, u.email_setting, u.num_posts, u.registered, u.admin_note, p.id, p.poster AS username, p.poster_id, p.poster_ip, p.poster_email, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by, g.g_id, g.g_user_title, o.user_id AS is_online FROM punbb_posts AS p INNER JOIN punbb_users AS u ON u.id=p.poster_id INNER JOIN punbb_groups AS g ON g.g_id=u.group_id LEFT JOIN punbb_online AS o ON (o.user_id=u.id AND o.user_id!=1 AND o.idle=0) WHERE p.topic_id=20821 ORDER BY p.id LIMIT 0,25
0.00143 UPDATE punbb_topics SET num_views=num_views+1 WHERE id=20821
Total query time: 0.00801 s