• 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

VPS Starter Arubacloud
0 głosów
486 wizyt
pytanie zadane 17 czerwca 2022 w C i C++ przez Noizz00 Użytkownik (910 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 2022 przez Oscar Nałogowiec (29,290 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 2022 przez Noizz00 Użytkownik (910 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 2022 przez Oscar Nałogowiec (29,290 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 2022 przez Noizz00 Użytkownik (910 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 2022 przez Great Stary wyjadacz (12,300 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ź 392 wizyt
pytanie zadane 12 stycznia 2017 w C i C++ przez kidcudi6 Nowicjusz (170 p.)
0 głosów
1 odpowiedź 1,812 wizyt
0 głosów
1 odpowiedź 1,154 wizyt
pytanie zadane 24 sierpnia 2017 w C i C++ przez Vendari Nowicjusz (150 p.)

92,452 zapytań

141,262 odpowiedzi

319,079 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...