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

Konstruktor, program się wiesza

0 głosów
91 wizyt
pytanie zadane 26 listopada 2016 w C i C++ przez Kacper777777 Bywalec (2,060 p.)

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,240 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 VIP (115,140 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 Kacper777777 Bywalec (2,060 p.)
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

0 głosów
2 odpowiedzi 84 wizyt
pytanie zadane 10 marca 2016 w Java przez piekarnik Użytkownik (720 p.)
0 głosów
1 odpowiedź 62 wizyt
pytanie zadane 5 lipca w C i C++ przez excavelty Obywatel (1,250 p.)
0 głosów
2 odpowiedzi 80 wizyt
Obowiązuje już zaktualizowany regulamin.

Czy wiesz, że nie musisz już odświeżać strony głównej?

Lista pytań i odpowiedzi aktualizuje się automatycznie!

38,556 zapytań

76,419 odpowiedzi

149,214 komentarzy

18,024 pasjonatów

Przeglądających: 253
Pasjonatów: 19 Gości: 234

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...