• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zapisanie danych do pliku .txt przy użyciu wskaźników

Object Storage Arubacloud
0 głosów
460 wizyt
pytanie zadane 2 października 2018 w C i C++ przez Kontrane Początkujący (260 p.)

Witam serdecznie wszystkich!

Proszę o pomoc w rozwiązaniu problemu :) Tworzę obiektowo e-dziennik w C++, którego jedną z funkcjonalności jest zapis utworzonej dynamicznie w programie listy uczniów (numerek, imię, nazwisko) do pliku .txt, aby później móc wczytać taką listę, taki dziennik, przy następnym uruchomieniu. 

Obecnie utknąłem w momencie zapisu listy do pliku .txt. Dodam, że w całym programie (piszę go w strukturze pliku projektowego - podział na 3 pliki) raczej nie mam problemu z operowaniem na utworzonej dynamicznie liście uczniów (lista jednokierunkowa). Oto ciało mojej metody:

void Lista::zapisz_dziennik()
{
    Uczen* temp=pierwszy;
    if(temp)
    {
        char nazwa[2];
        cout<<"Podaj nazwę klasy (np. 1B): ";
        cin>>nazwa;
        fstream plik;
        plik.open(nazwa, ios::out);
        while(temp->nastepny)
        {
            plik<<temp->nr<<" "<<temp->imie<<" "<<temp->nazwisko<<endl;
            temp=temp->nastepny;
        }
        plik<<temp->nr<<" "<<temp->imie<<" "<<temp->nazwisko;

        cout<<"Zapisuje dziennik klasy "<<nazwa;
        Sleep(250);
        cout<<".";
        Sleep(250);
        cout<<".";
        Sleep(250);
        cout<<".";
        Sleep(250); //animacja
        plik.close();
    }
    else
    {
        cerr<<"\aBłąd. Dziennik jest pusty!";
        Sleep(2000);
    }
}

Problem pojawia się jedynie przy zapisie danych do pliku .txt (analogiczny cout<<temp->nr<<" "... itd. działa bez problemu - napisałem nawet specjalną metodę bardzo zbliżoną do tej, do wyświetlania całej listy na oknie konsoli).

Przy wpisaniu chociaż jednego ucznia, zamiast zapisu w notatniku w stylu:

1 Jan Kowalski

otrzymuję

33556432 (adres w pamięci RAM?)

Pozdrawiam wszystkich serdecznie i liczę na pomoc :)

PS Od razu dodam, dołączyłem bibliotekę <fstream>!

komentarz 2 października 2018 przez niezalogowany
A jak wstawisz na stale nazwe pliku to tez nie dziala ?

1 odpowiedź

0 głosów
odpowiedź 3 października 2018 przez draghan VIP (106,230 p.)

Samo zapisywanie wygląda w porządku. Za to gorzej z otwieraniem pliku.

1. Masz za mały bufor na nazwę - zapomniałeś, że C-stringi są zakończone znakiem terminującym '\0'. Jeśli nazwa pliku ma być dwuznakowa - potrzebujesz trzy miejsca w buforze. A w ogóle lepiej użyć std::string i nie zaprzątać sobie tym głowy.

2. Nie sprawdzasz, czy plik poprawnie się otworzył.

std::string nazwa;
cout<<"Podaj nazwę klasy (np. 1B): ";
cin>>nazwa;
ofstream plik(nazwa); // obiekt ofstream (output-file-stream) domyslnie otwiera sie w trybie do zapisu
if(!plik.good())
{
    std::cerr << "Nie udalo sie otworzyc pliku!";
    return;
}

 

komentarz 10 października 2018 przez Kontrane Początkujący (260 p.)
Pięknie dziekuję! Oczywiście problemem był za mały rozmiar tablicy char na nazwę klasy, po zmianie z [2] na [3] wszystko działa (tak to jest, jak całe życie używa się stringa). A stringa niestety nie można użyc, ponieważ metoda open za argument bierze chara,  a nie stringa :(

Pozdrawiam!
komentarz 10 października 2018 przez draghan VIP (106,230 p.)

metoda open za argument bierze chara,  a nie stringa :(

Od C++11 wzwyż jest dostępne przeciążenie metody open dla ścieżki podanej jako std::string [patrz (3)]. Tak samo z konstruktorem.

W ogóle nie potrzebujesz używać metod open i close - jeśli podasz ścieżkę do pliku w konstruktorze, strumień do tego pliku się otworzy i nie będzie potrzeby wołania open. Zaś zamykanie strumienia odbywa się automatycznie w destruktorze, więc nie ma też potrzeby wołania close. Chyba, że chcesz użyć danej zmiennej ponownie (a Ty nie używasz). Czy to nie ładniejsze? :)

if(temp)
{
    std::string nazwa;
    cout<<"Podaj nazwę klasy (np. 1B): ";
    cin>>nazwa;
    ofstream plik(nazwa); // obiekt ofstream (output-file-stream) domyslnie otwiera sie w trybie do zapisu
    if(!plik.good())
    {
        std::cerr << "Nie udalo sie otworzyc pliku!";
        return;
    }

    while(temp->nastepny)
    {
        plik<<temp->nr<<" "<<temp->imie<<" "<<temp->nazwisko<<endl;
        temp=temp->nastepny;
    }
    plik<<temp->nr<<" "<<temp->imie<<" "<<temp->nazwisko;

    cout<<"Zapisuje dziennik klasy "<<nazwa;
    Sleep(250); // Sleep jest nieprzenośny, dobrze byłoby tego unikać
    cout<<".";
    Sleep(250);
    cout<<".";
    Sleep(250);
    cout<<".";
    Sleep(250); //animacja
} // wraz z opuszczeniem tego zakresu, zmienna 'plik' jest usuwana, przy czym 
  // wywoływany jest jej destruktor, co automatycznie zamyka strumień

Pozdrawiam!

Pozdrawiam również. :)

Podobne pytania

+3 głosów
4 odpowiedzi 1,709 wizyt
pytanie zadane 30 czerwca 2015 w C i C++ przez Phobos Użytkownik (720 p.)
+1 głos
0 odpowiedzi 119 wizyt
pytanie zadane 12 czerwca 2020 w C i C++ przez amtrax Dyskutant (9,630 p.)
0 głosów
2 odpowiedzi 497 wizyt
pytanie zadane 14 lipca 2020 w C i C++ przez Kxmil Nowicjusz (220 p.)

92,555 zapytań

141,403 odpowiedzi

319,560 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...