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.