• 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

0 głosów
60 wizyt
pytanie zadane 16 czerwca w C i C++ przez Noizz00 Początkujący (420 p.)
zamknięte 16 czerwca 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 przez Kartoszka Obywatel (1,140 p.)
wybrane 16 czerwca 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 przez overcq Pasjonat (17,750 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 przez Noizz00 Początkujący (420 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 przez Oscar Nałogowiec (25,590 p.)
A cofasz wskaźniki przed wykonaniem delete[] ?

Podobne pytania

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

88,311 zapytań

136,904 odpowiedzi

305,517 komentarzy

58,593 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.

...