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

Program przestał działać - błąd

Object Storage Arubacloud
+1 głos
321 wizyt
pytanie zadane 16 lutego 2021 w C i C++ przez Informatyk_44 Nowicjusz (150 p.)
#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

class towary
{
	public:
		string nazwa;
		int ilosc;
		int cena;
};

int main()
{
    int nr;
    int ile;
    cout<<"Na poczatku dodaj towary do bazy danych"<<endl<<endl;
    cout<<"Ile pozycji chcesz dodac?"<<endl;
    cin>>ile;
    towary towar[ile];
    for (int i=1;i<=ile;i++)
          {
            system("cls");
			cout<<"Dodawanie nowego towaru: "<<endl;
			cout<<"Podaj nazwe: ";
			cin>>towar[i].nazwa;
			cout<<"Podaj ilosc: ";
			cin>>towar[i].ilosc;
			cout<<"Podaj cene: ";
			cin>>towar[i].cena;
			cout<<"Dodano nowy towar!"<<endl;
          }



do{

    cout<<"1. Wyswietl liste towarow"<<endl;
    cout<<"2. Usun towar"<<endl;
    cout<<"3. Zapisz liste towarow do pliku"<<endl;
    cout<<"4. Wczytaj liste towarow z pliku"<<endl;
    cout<<"5. Wyczysc ekran"<<endl;
    cout<<"0. Wyjdz z programu"<<endl;
    cout<<endl;
    cin>>nr;

    switch(nr)
    {
    	case 1:
    	   {

    		cout<<"Lista towarow:"<<endl<<endl;

                for(int i=1;i<=ile;i++)
                {
                    cout<<"Towar nr. "<<i<<": "<<endl;
                    cout<<"Nazwa: "<<towar[i].nazwa<<endl;
                    cout<<"Ilosc: "<<towar[i].ilosc<<endl;
                    cout<<"Cena: "<<towar[i].cena<<endl;
                }
            system("PAUSE");
        break;
    	   }
    	case 2:
{
       int numer;
       cout<<"Podaj numer towaru do usuniecia: ";
       cin>>numer;
       {
       if (ile>=1)
       {
          towar[numer]=towar[ile-1];
          ile--;

       }
       else cout<<"Lista zapisanych towarow jest pusta!"<<endl;
       }
    	break;
}
        case 3:
        	{
        	    ofstream plik;
        	    plik.open("towary.txt");
        	    for(int i=1;i<=ile;i++)
        	    {
        	        plik<<"Nazwa towaru nr "<<i<<": "<<endl;
        	        plik<<towar[i].nazwa<<endl;
        	        plik<<"Ilosc towaru nr "<<i<<": "<<endl;
        	        plik<<towar[i].ilosc<<endl;
        	        plik<<"Cena towaru nr "<<i<<": "<<endl;
        	        plik<<towar[i].cena<<endl<<endl;
        	    }
        	    cout<<"Zapisano do pliku!"<<endl;
        	    plik.close();
        	    cin.get();
        	    break;
            }

        case 4:
        	{
                char dane;
                ifstream plik;
                plik.open("towary.txt");
                if(!plik.is_open())
                    {
                    cout<<"Nie znaleziono pliku!"<<endl;
                    }
                plik>>noskipws>>dane;
                while(plik.good())
                    {
                    cout<<dane;
                    plik>>dane;
                    };
                break;
            }
        case 5:
        	system("cls");
        break;
        case 0:
            return 1;
        break;
        default:
            {
    		cout<<"wpisz poprawna liczbe!"<<endl;
            break;
    		}
        return (0);
     }
   }while(nr!='0');
}

Witam, mam problem z napisanym przez siebie programem. Jest to prosta baza towarów, która na początku prosi o dodanie towarów. Przy dodawaniu ostatniego towaru, podczas wpisywania nazwy, program wyłącza się. Nie mam pojęcia co zrobić aby ten błąd usunąć, proszę o pomoc. Pozdrawiam 

2 odpowiedzi

+2 głosów
odpowiedź 17 lutego 2021 przez TOM_CPP Pasjonat (22,640 p.)

Błąd zapewne znajduje się w tym fragmencie kodu:

cin>>ile;
towary towar[ile];
for (int i=1;i<=ile;i++)
{
      system("cls");
      cout<<"Dodawanie nowego towaru: "<<endl;
      cout<<"Podaj nazwe: ";
      cin>>towar[i].nazwa;
      cout<<"Podaj ilosc: ";
      cin>>towar[i].ilosc;
      cout<<"Podaj cene: ";
      cin>>towar[i].cena;
      cout<<"Dodano nowy towar!"<<endl;
}

W C++ indeksy tablic zaczynają się od zera i kończą na liczbie która jest o jeden mniejsza od rozmiaru tablicy ( tutaj jest to  ile-1 ). Jeżeli pominięcie pierwszego elementu nie jest jeszcze dużym błędem, to zapisanie czegoś poza zakresem tablicy jest bombą z opóźnionym zapłonem, który nazywa się fachowo Undefined behavior. Dzieje się tak gdyż próbujesz zapisać w tablicy obiekt klasy towary w tablicy o indeksie ile , gdzie tablica nie ma już zarezerwowanej pamięci.

Zmień ten kod używając std::vector lub std::array zamiast zwykłej tablicy.

cin>>ile;
std::vector<towary> towar(ile);

for ( auto& item : towar )
{
      system("cls");
      cout<<"Dodawanie nowego towaru: "<<endl;
      cout<<"Podaj nazwe: ";
      cin>>item.nazwa;
      cout<<"Podaj ilosc: ";
      cin>>item.ilosc;
      cout<<"Podaj cene: ";
      cin>>item.cena;
      cout<<"Dodano nowy towar!"<<endl;
}

 

+1 głos
odpowiedź 17 lutego 2021 przez Whiskey_Taster Pasjonat (15,610 p.)

Oj błędy są. 

  • linia nr 22: tworzysz tablicę o rozmiarze, który w domyśle jest podany przez użytkownika. Jednakże w C++ tak się tego nie robi, bo alokując w ten sposób tablicę rozmiar musi być znany w momencie kompilacji. A w Twoim przypadku tak nie jest. Dlatego też radzę zadziałać z operatorem new
  • linia 23: koszmarne zrozumienie posługiwania się indeksami w tablicach. Zawsze zaczynamy liczyć od 0, nigdy od 1. Wobec tego pierwszym elementem n-elementowej tablicy jest 0, zaś ostatnim indeksem jest n-1
  • linia 56: to samo co linia 23
  • linia 101: w tym case otwierasz plik, ale go nie zamykasz. A to też jest błąd. 

To tak na pierwszy rzut oka

2
komentarz 17 lutego 2021 przez tkz Nałogowiec (42,000 p.)
Ostatnia kropka, od tego jest destruktor.
1
komentarz 17 lutego 2021 przez Whiskey_Taster Pasjonat (15,610 p.)
Masz rację, w końcu wyjdzie ze switch'a, więc destruktor zostanie wywołany. Nie uwzględniłem tego.

Podobne pytania

+1 głos
1 odpowiedź 484 wizyt
pytanie zadane 5 października 2021 w C i C++ przez Hpst Nowicjusz (130 p.)
0 głosów
1 odpowiedź 194 wizyt
0 głosów
1 odpowiedź 277 wizyt

92,536 zapytań

141,377 odpowiedzi

319,452 komentarzy

61,922 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!

...