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

Konstruktor, program się wiesza

VPS Starter Arubacloud
0 głosów
198 wizyt
pytanie zadane 26 listopada 2016 w C i C++ przez niezalogowany

Napisałem sobie klasę menu, i wszystko działało, gdy kod wyglądał tak:

main.cpp

#include <iostream>
#include <fstream>
#include "menu.h"

using namespace std;

int main()
{
    fstream plik2;
    string linia2;

    int nr_linii=0;
    plik2.open("kategorie.txt", ios::in);
    while(getline(plik2,linia2))
        nr_linii++;
    plik2.close();

	Menu m("",1,nr_linii,1);

    string *wskaznik=m.opcje;

    plik2.open("kategorie.txt", ios::in);
    while(getline(plik2,linia2))
    {
        *wskaznik=linia2;
        wskaznik++;
    }
    plik2.close();
    cout<<endl;

    while(m.str_wybor!="z")
    {
        m.wyswietl();
        m.wybierz();
        //cout<<m.ile<<endl;
    }

    //m.wyswietl();

    return 0;
}

menu.h

#include <iostream>

using namespace std;

class Menu
{
	public:

	string str_wybor;
	int ile;
	string opcje[1000];

	Menu(string,int,int,int);
	void wyswietl(); //wyświetla główne opcje w menu
	void wybierz(); //czyta wybór użytkownika

	private:

	int wybor;
	int pom;

};

menu.cpp

#include <iostream>
#include <fstream>
#include <cstdlib>
#include "menu.h"
#include "text.h"

using namespace std;

Menu::Menu(string a,int b,int c,int d)
{
	str_wybor=a;
	wybor=b;
	ile=c;
	pom=d;
}

void Menu::wyswietl()
{
	fstream plik;
	string linia;

	plik.open("tymczasowe menu.txt", ios::out);

	pom = 1;
	for(int l=0; l<ile; l++)
    {
		if(l==0)
		{
			cout<<opcje[l]<<endl<<endl;
			plik<<opcje[l]<<endl<<endl;
		}
		else
		{
			if(  int(opcje[l][0])!=9  )
			{
				cout<<pom<<". "<<opcje[l]<<endl;
				pom++;
			}
			plik<<opcje[l]<<endl;
		}
    }

	plik.close();
}

void Menu::wybierz()
{
	cout<<"\nWprowadź wybór: ";
	bool czy_wybrano=false;
	if(str_wybor!="")
		czy_wybrano=true;

	cin>>str_wybor;

	while(  !((is_int_convert(str_wybor) && atoi(str_wybor.c_str())>0 && atoi(str_wybor.c_str())<pom) || (str_wybor=="z" && czy_wybrano==true))  )
	{
		if(str_wybor=="z" && czy_wybrano==false)
		{
			cout<<"Nie wprowadzono wyboru\n";
			cin>>str_wybor;
		}
		else
		{
			cout<<"Nieprawidłowe dane. Wprowadź jeszcze raz\n";
			cin>>str_wybor;
		}
	}

	if( str_wybor != "z")
	{
		pom=1;
		wybor = atoi(str_wybor.c_str());

		//////////////////////////////
		for(int i=0; i<=ile; i++)
			opcje[i] = "";

		int i=0;
		fstream plik;
		string linia;

		plik.open("tymczasowe menu.txt", ios::in);

		while(getline(plik,linia))
		{
			if(linia.size()==0)
				continue;
			opcje[i] = linia;
			i++;
		}

		plik.close();
		//////////////////////////////

		i=0; 	 //do indeksowania linii w menu
		int j=0; //do indeksowania linii w nowo tworzonym menu
		int temat=0;

		while(i<ile)
		{
			if( int(opcje[i][0])!=9 && i!=0 )
				temat++;

			if(temat == wybor)
			{
				if(is_int_convert(opcje[i]))
				{
					str_wybor = "z";
				}

				opcje[j]=opcje[i];
				j++;
				i++;

				while( int(opcje[i][0])==9 )
				{
					opcje[j]=opcje[i].erase(0,1);
					j++;
					i++;
				}

				ile=j;
				j=0;
			}

			i++;
		}
	}
}

 

Jednak pomyślałem, że można stworzyć wskażnik do tablicy i w konstruktorze ją zapełnić inną tablicą, żeby było mniej kodu żródłowego i mniej zużycia pamięci.

main.cpp

#include <iostream>
#include <fstream>
#include "menu.h"

using namespace std;

int main()
{
    fstream plik2;
    string linia2;

    int nr_linii=0;
    plik2.open("kategorie.txt", ios::in);
    while(getline(plik2,linia2))
        nr_linii++;
    plik2.close();

    string *tablica;
    tablica = new string [nr_linii];
    string *wskaznik=tablica;

    plik2.open("kategorie.txt", ios::in);
    while(getline(plik2,linia2))
    {
        *wskaznik=linia2;
        wskaznik++;
    }
    plik2.close();

	Menu m("",1,nr_linii,1,tablica);

    while(m.str_wybor!="z")
    {
        m.wyswietl();
        m.wybierz();
    }

    return 0;
}

menu.h

#include <iostream>

using namespace std;

class Menu
{
	public:

	string str_wybor;
	int ile;
	string *opcje;

	Menu(string,int,int,int,string*);
	~Menu();
	void wyswietl(); //wyświetla główne opcje w menu
	void wybierz(); //czyta wybór użytkownika

	private:

	int wybor;
	int pom;

};

menu.cpp

#include <iostream>
#include <fstream>
#include <cstdlib>
#include "menu.h"
#include "text.h"

using namespace std;

Menu::Menu(string a,int b,int c,int d, string *tab)
{
	str_wybor=a;
	wybor=b;
	ile=c;
	pom=d;

	opcje = new string [ile];

	string *wsk1 = opcje;
	string *wsk2 = tab;

	for(int i=0; i<ile; i++)
    {
        *wsk1 = *wsk2;
        wsk1++;
        wsk2++;
    }
}

Menu::~Menu()
{
    delete [] opcje;
}

void Menu::wyswietl()
{
	fstream plik;
	string linia;

	plik.open("tymczasowe menu.txt", ios::out);

	pom = 1;
	for(int l=0; l<ile; l++)
    {
		if(l==0)
		{
			cout<<opcje[l]<<endl<<endl;
			plik<<opcje[l]<<endl<<endl;
		}
		else
		{
			if(  int(opcje[l][0])!=9  )
			{
				cout<<pom<<". "<<opcje[l]<<endl;
				pom++;
			}
			plik<<opcje[l]<<endl;
		}
    }

	plik.close();
}

void Menu::wybierz()
{
	cout<<"\nWprowadź wybór: ";
	bool czy_wybrano=false;
	if(str_wybor!="")
		czy_wybrano=true;

	cin>>str_wybor;

	while(  !((is_int_convert(str_wybor) && atoi(str_wybor.c_str())>0 && atoi(str_wybor.c_str())<pom) || (str_wybor=="z" && czy_wybrano==true))  )
	{
		if(str_wybor=="z" && czy_wybrano==false)
		{
			cout<<"Nie wprowadzono wyboru\n";
			cin>>str_wybor;
		}
		else
		{
			cout<<"Nieprawidłowe dane. Wprowadź jeszcze raz\n";
			cin>>str_wybor;
		}
	}

	if( str_wybor != "z")
	{
		pom=1;
		wybor = atoi(str_wybor.c_str());

		//////////////////////////////
		//for(int i=0; i<=ile; i++) //CZEMU PO ZAKOMENTOWANIU TEGO ZADZIAŁAŁO??????????
		//	opcje[i] = "";          //A JAK NIE ZAKOMENTOWANE TO PROGRAM SIĘ WIESZA

		int i=0;
		fstream plik;
		string linia;

		plik.open("tymczasowe menu.txt", ios::in);

		while(getline(plik,linia))
		{
			if(linia.size()==0)
				continue;
			opcje[i] = linia;
			i++;
		}

		plik.close();
		//////////////////////////////

		i=0; 	 //do indeksowania linii w menu
		int j=0; //do indeksowania linii w nowo tworzonym menu
		int temat=0;

		while(i<ile)
		{
			if( int(opcje[i][0])!=9 && i!=0 )
				temat++;

			if(temat == wybor)
			{
				if(is_int_convert(opcje[i]))
				{
					str_wybor = "z";
				}

				opcje[j]=opcje[i];
				j++;
				i++;

				while( int(opcje[i][0])==9 )
				{
					opcje[j]=opcje[i].erase(0,1);
					j++;
					i++;
				}

				ile=j;
				j=0;
			}

			i++;
		}
	}
}

 

W metodzie wybierz napisałem dużymi literami o co chodzi. Oczywiście mogę to mieć zakomentowane i wtedy program się nie wiesza, ale w komórkach tablicy siedzą różne dane i w przypadku gdy wybory użytkownika to będą 1 i 3 to wyświetlą się 4 opcje, a powinny 3 (wiem bo tak jest w pliku kategorie.txt). Muszę więc zerować komórki tablicy i korzystać z pliku "tymczasowe menu.txt". Ale nie rozumiem czemu linijki

for(int i=0; i<=ile; i++)

 opcje[i] = "";

sprawiają, że program się zawiesza.

komentarz 26 listopada 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Nie próbowałem kompilować Twojego projektu, jednak rzucił mi się w oczy zakres jaki próbujesz przejść po pętli, czy nie jest on za duży o 1? (mniejsze, nie mniejsze równe)

for(int i=0; i<ile; i++)
   opcje[i] = "";         

2 odpowiedzi

+2 głosów
odpowiedź 26 listopada 2016 przez criss Mędrzec (172,590 p.)
W pętli for powinien być znak < zamiast <=. Nie wczytywałem sie bardziej w kod, ale prawdopodobnie to powoduje crash.
0 głosów
odpowiedź 26 listopada 2016 przez niezalogowany
Tak, ale jak wezmę < to program nie działa do końca poprawnie, a w tej pierwszej wersji było <= i program działał poprawnie. Problemy się zaczęły dopiero gdy zacząłem kombinować z tymi wskaźnikami i konstruktorem.

Podobne pytania

+1 głos
1 odpowiedź 178 wizyt
pytanie zadane 23 kwietnia 2019 w C i C++ przez Milo Obywatel (1,180 p.)
0 głosów
2 odpowiedzi 533 wizyt
pytanie zadane 10 marca 2016 w Java przez piekarnik Użytkownik (720 p.)
0 głosów
1 odpowiedź 174 wizyt
pytanie zadane 19 sierpnia 2019 w C i C++ przez shnycell Nowicjusz (140 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

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

...