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

question-closed Kompilator nie zwraca błędów, a program nie działa tak, jak powinien

VPS Starter Arubacloud
0 głosów
247 wizyt
pytanie zadane 16 czerwca 2022 w C i C++ przez Noizz00 Użytkownik (910 p.)
zamknięte 16 czerwca 2022 przez Noizz00

Witam,

napisałem niedawno program pobierający od użytkownika zestawy danych typu: imię, nazwisko, numer telefonu, coś w stylu programu z kursu p. Zelenta z odcinka o plikach tekstowych, tylko bardziej rozbudowany.

Zająłem się napisaniem pierwszego przypadku, czyli takiego, w którym program pyta się, ile zestawów danych użytkownik chce wpisać, prosi o podanie tych danych, zapisuje je do tablicy, a następnie przekazuje je do pliku, wykorzystałem w tym celu wskaźniki. Program poniżej (z paroma komentarzami):

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <conio.h>
#include <cstring>

using namespace std;

int ile;
char wybor;

int main()
{
    // Wyswietlenie menu glownego
    cout << "Witaj!" << endl;
    cout << "1. Utworzenie nowego pliku." << endl;
    cout << "2. Zastapienie danych istniejacego pliku." << endl;
    cout << "4. Nadpisanie danych istniejacego pliku." << endl;
    cout << "5. Wyswietlenie danych istniejacego pliku." << endl;
    cout << "6. Wyjscie z programu."<<endl;
    cout << "Co chcesz zrobic? Wybierz wlasciwy numer: ";
    wybor=getch(); // Pobranie znaku z klawiatury
    switch(wybor)
    {
        case '1': // Wykonaj, je¿eli uzytkownik chce utworzyc nowy plik
        {
            system("cls");
            cout << "Ile zestawow danych zawierajacych: ";
            cout << endl << "imie osoby,";
            cout << endl << "nazwisko osoby,";
            cout << endl << "numer telefonu osoby,";
            cout << endl << "chcesz podac?";
            cin >> ile; // Zapisanie do zmiennej 'ile' ilosci zestawow danych
            system("cls"); // Wyczyszczenie zawartosci ekranu
            string *imie, *nazwisko;
            int *nr_tel;
            imie = new string [ile]; // Utworzenie tablicy do imion
            nazwisko = new string [ile]; // Utworzenie tablicy do nazwisk
            nr_tel = new int [ile]; // Utworzenie tablicy do numerow telefonow
            for(int i=0; i<ile; i++) // Podanie danych
            {
                cout << "Podaj "<<i+1<<". imie: ";
                cin >> *imie;
                cout << "Podaj "<<i+1<<". nazwisko: ";
                cin >> *nazwisko;
                cout << "Podaj "<<i+1<<". numer telefonu: ";
                cin >> *nr_tel;
                imie++; nazwisko++; nr_tel++;
                system("cls"); // Wyczyszczenie ekranu po podaniu danych dla jednego zestawu
            }
            fstream plik; // Utworzenie zmiennej do operacji na pliku tekstowym
            plik.open("zestawy_danych.txt", ios::out); // Otworzenie pliku tekstowego
            for(int i=0; i<ile; i++) // Przekazanie danych z tablic do pliku
            {
                plik<<imie[i]<<endl;
                plik<<nazwisko[i]<<endl;
                plik<<nr_tel[i]<<endl;
            }
            plik.close(); // Zamkniecie pliku
            delete [] imie; delete [] nazwisko; delete [] nr_tel; // Zwolnienie pamieci
            break; // Przerwanie case'a '1'
        }
    }
    return 0;
}

Program działa poprawnie do momentu podania wszystkich zestawów danych. Potem na konsoli miga biały kursor i nic dalej się nie dzieje. Plik tekstowy jednak został utworzony (znajduje się w folderze projektu), ale jest pusty. Ktoś miałby pomysł, co może być w programie nie tak? Czy jest to problem z czymś innym? Prosiłbym o jak najprostsze wyjaśnienia ;) 

komentarz zamknięcia: Znaleziono odpowiedź.

3 odpowiedzi

+2 głosów
odpowiedź 16 czerwca 2022 przez Kartoszka Obywatel (1,260 p.)
wybrane 16 czerwca 2022 przez Noizz00
 
Najlepsza
Używając pointer++ (imie, nazwisko, tel) przesuwasz go na kolejną pozycje - z tego też korzystasz w forze z linii 40. Ale przy zapisie do plików (for 53) wiąż odwołujesz się do ich nowych wartości - tych przesuniętych. Przy pierwszej próbie zapisu do pliku wychodzisz poza tablice.

Możesz albo użyć arytmetyki wskaźników, lub działać w forze z linii 40 tak jak w tym z linii 53.
Ewentualnie zrobić pointer na pointera i na nim działać, lub po forze "cofnąć" pointery do miejsaca w które pierwotnie wskazywały.
0 głosów
odpowiedź 16 czerwca 2022 przez overcq Pasjonat (21,540 p.)

Nie kompilowałem tego programu, ale widzę, że przesuwasz wskaźniki imienazwisko i nr_tel, a później – podczas pisania do pliku – odwołujesz się względem ich pierwotnych wartości.

0 głosów
odpowiedź 16 czerwca 2022 przez Noizz00 Użytkownik (910 p.)

Dzięki wszystkim, jak sugerowaliście, po pobraniu zestawów dodałem linie:

imie-=ile;
nazwisko-=ile;
nr_tel-=ile;

a później w pętli skorzystałem ze wskaźników zamiast z odczytywania tablic:

for(int i=0; i<ile; i++) // Przekazanie danych z tablic do pliku
            {
                plik<<*imie<<endl;
                plik<<*nazwisko<<endl;
                plik<<*nr_tel<<endl;
                imie++; nazwisko++; nr_tel++;
            }

I teraz działa to jak powinno. Jeszcze raz, wielkie dzięki :)

komentarz 16 czerwca 2022 przez Oscar Nałogowiec (29,290 p.)
A cofasz wskaźniki przed wykonaniem delete[] ?

Podobne pytania

–1 głos
4 odpowiedzi 231 wizyt
pytanie zadane 13 stycznia 2019 w Java przez ShockOfficial Początkujący (390 p.)
0 głosów
2 odpowiedzi 228 wizyt
+1 głos
1 odpowiedź 147 wizyt

92,454 zapytań

141,262 odpowiedzi

319,089 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!

...