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

Zapis i odczyt pliku tekstowego z użyciem wskaźników i procedur

0 głosów
74 wizyt
pytanie zadane 17 czerwca w C i C++ przez Noizz00 Użytkownik (660 p.)

Witam, napisałem program do zapisywania i odczytu zestawów danych w postaci:


imie

nazwisko

numer telefonu


przechowywanych w pliku tekstowym, coś na wzór programu z kursu p. Zelenta o plikach tekstowych. 

Problem 1: Kod z wykorzystaniem wskaźników (LINK) działa, jednak nie tak jakbym tego chciał. Po wykonaniu każdego przypadku nie wykonuje instrukcji za switchem i nie przechodzi do kolejnej iteracji, tylko od razu wywołuje zamknięcie. 

Problem 2: Próbowałem przekształcić kod z problemu 1 tak, aby wykorzystywał procedury (LINK), żeby skrócić kod programu. Problem tkwi w tym, że przy linijkach z wywołaniem procedur (81, 89, 91, 99, 101, 109) konsola zwraca błąd w postaci


error: use of deleted function 'std::basic_fstream<_CharT, _Traits>::basic_fstream(const std::basic_fstream<_Char_T, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'


możliwe, że nie do końca zrozumiałem istotę procedur i zapisałem je w zły sposób, albo być może nie jest możliwe to, co chciałbym osiągnąć. Programuję dopiero od jakiś dwóch tygodni, dlatego prosiłbym o w miarę proste wyjaśnienia :) Będę wdzięczny za pomoc. W kodach oczywiście zamieściłem komentarze (do większości linijek).

1
komentarz 17 czerwca przez Oscar Nałogowiec (26,410 p.)
Wrzuć ten kod. Wiem to w sumie złączenie dwóch poprzednich pytań, ale warto byłoby zobaczyć całość.

Trzeci raz: czy odtwarzasz oryginalną wartość wskaźników przed delete[]? Raz miałeś już z tym problem, w jedym miejscu poprawiłeś, ale musisz to powtórzyć przed zwolnieniem pamięci.
komentarz 17 czerwca przez Noizz00 Użytkownik (660 p.)
Kody są pod linkami w pastebinie, nie widać ich?

Jeśli chodzi o odtwarzanie oryginalnej wartości, za pierwszym razem w poprzednim pytaniu musiałem nie do końca zrozumieć co miałeś na myśli, teraz jednak już rozumiem :) zrobiłem to już po każdej pętli for która zmienia pozycje wskaźników, teraz działa jak należy. Dzięki. Problem 1 rozwiązany. Pozostał problem 2 :/
1
komentarz 17 czerwca przez Oscar Nałogowiec (26,410 p.)

Faktycznie są linki - moje gapiostwo, poprzednio wrzucałeś kod do posta i tego szukałem.

Obejrzałem kod 2 i widzę, masz tam jedną nietrywialną funkcję

void zapis(fstream p, string *im, string *na, int *nt);

Wewnątrz funkcji allokujesz tablice im, na i nt i je zwalniasz. Zupełnie nieistotna jest wartość początkowa tych wskaźników (i tak nic nie ma zaallokowane) - niepotrzebnie to są parametry - wystarczy jak będą zmienne lokalne funkcji.

Z kolei p - trochę dziwnie obsługujesz plik - otwierasz go w main a zamykasz w funkcji zapis.

Pierwszy problem - przekazanie parametru to jak utworzenie zmiennej lokalnej zainicjowanej wartością z jaką została wywołana funkcja. Nie wiem, czy obiekty fstream można tak sobie przypisywać i to będzie działać. Być może tak. W czasie wykonywania funkcji masz w rzeczywistości dwie zmienne typu fstream: plik w main i p w funkcji - obie powiązane z tym samym plikiem. Zwykle jednak w takiej sytuacji przekazuje się wskaźnik lub referencję do obiektu - wtedy jest fizycznie jedna zmienna kontrolująca plik.

Druga sprawa to otwieranie i zamykanie na różnych poziomach. Ładniej jest stosować zasadę, że parowane operacje (open/close, new/delete itp) występują na tym samym poziomie kodu. Czylo albo otwieramy w main, przekazujemy do funkcji by sobie zapisała i po powrocie do main zamykamy, albo wszystko w funkcji, najwyżej przekazujemy nazwę pliku.

Trochę też dziwnie masz dwa fragmenty kodu:

                plik.open("zestawy_danych.txt", ios::out);
                zapis(plik, imie, nazwisko, nr_tel);
                plik.open("zestawy_danych.txt", ios::out);
                if(plik.good()==false)
                {
                    wyjscie(plik);
                    break;
                }
                zapis(plik, imie, nazwisko, nr_tel);

Dwa razy dokładnie tak samo otwierasz plik, w pierwszym przypadku nic nie sprawdzasz, a w drugim zakładasz że wykryjesz fakt, czy plik istniał. To tak nie działa.

komentarz 17 czerwca przez Noizz00 Użytkownik (660 p.)
Spróbowałem zamienić fstream p na fstream &p i zadziałało. Za twoją radą wyciągnąłem polecenia zamknięcia pliku do int  main() i zamieniłem wskaźniki *im, *na i *nt na zmienne lokalne. Zcaliłem case'y 1 i 2, bo w sumie robiły to samo. Program jest już (jak na moje możliwości i potrzeby) w pełni funkcjonalny. Bardzo dziękuję za pomoc!

1 odpowiedź

0 głosów
odpowiedź 17 czerwca przez Great Dyskutant (7,860 p.)

Przekaż obiekt klasy std::fstream przez referencję. Nie możesz kopiować go, ponieważ konstruktor kopiujący jest usunięty:

basic_fstream( const basic_fstream& rhs) = delete;

  (since C++11)

 Zmienna ilosc_linii jest niezainicjalizowana. 

Podobne pytania

0 głosów
1 odpowiedź 205 wizyt
pytanie zadane 12 stycznia 2017 w C i C++ przez kidcudi6 Nowicjusz (170 p.)
0 głosów
1 odpowiedź 1,457 wizyt
0 głosów
1 odpowiedź 875 wizyt
pytanie zadane 24 sierpnia 2017 w C i C++ przez Vendari Nowicjusz (150 p.)

88,720 zapytań

137,331 odpowiedzi

306,818 komentarzy

58,907 pasjonatów

Motyw:

Akcja Pajacyk

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

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...