Wczytanie tekstu z pliku do tablicy

0

Witajcie. Piszę aplikację quiz. W sumie mam ją już ukończoną, ale bardzo amatorsko. Aplikacja napisana jest w C++ Builder. Chodzi mi o wczytywanie pytań i odpowiedzi do programu. Aktualnie wykonuje to tak:

void __fastcall TForm1::Wczytaj()
{
       fstream plik;
       plik.open("pyt.txt", ios::in);

       if(plik.good() == false)
       {
              ShowMessage("Błąd! Nie udało się wczytac pliku!");
              exit(0);
       }

       int nr_linii = (nr_pytania - 1) * 5 + 1;
       int aktualny_nr = 1;

       while(getline (plik, Linia))
       {
              if(aktualny_nr == nr_linii) Tresc = Linia;
              if(aktualny_nr == nr_linii + 1) A = Linia;
              if(aktualny_nr == nr_linii + 2) B = Linia;
              if(aktualny_nr == nr_linii + 3) C = Linia;
              if(aktualny_nr == nr_linii + 4) Poprawna = Linia;
              aktualny_nr++;
       }
       plik.close();
       Wypisz();
}

screenshot-20171109202001.png

Czyli za każdym kliknięciem przycisku "Następne" wykonuje się ponownie wczytanie danych z pliku. Ja chcę, aby to zrobić tak, że w aplikacji użytkownik sam wskazuje plik, który ma zostać wczytany i wczytuje go do tablicy całościowo od razu. Czy jest taka możliwość?

0

Klasa TForm2

class TForm2 : public TForm
{
     __published:

     public:
       string Linia, Tresc, A, B, C, Poprawna, Odpowiedz;
       int nr_pytania, punkt, czas;
       vector < string > tab;

       void __fastcall Wczytaj(); 
       void __fastcall Wypisz(int nr); 
       void __fastcall Sprawdz();  
       void __fastcall Zapisz(); 
       void __fastcall LiczCzas();

       __fastcall TForm2();

};
void __fastcall TForm2::Wczytaj()
{
       if (Form1 -> OpenDialog1 -> Execute())
        {
                ifstream plik (Form1 -> OpenDialog1 -> FileName.c_str());
                if (plik.good() == false)
                {
                        ShowMessage("Błąd. Wskaż prawidłowy plik!");
                }
                else {
                        while (getline(plik, Linia)) tab.push_back(Linia);
                        plik.close();
                        Form1 -> Tekst_BladNazwisko -> Caption = "Plik wczytano poprawnie!";
                        Form1 -> Przycisk_Start -> Enabled = true;
                }

        }
}

W Form1 mam wszystkie przyciski itp. (elementy wizualne)
Po skompilowaniu programu, wczytaniu pliku wywala błąd:
Bez tytułu.jpg

i otwiera się debugger z podświetloną tą linijką:

  bool empty() const { return this->_M_start == this->_M_finish; }   

Zauważyłem, że jeżeli jest wszystko w jednej klasie to nie ma żadnych problemów!

0

Zgaduję, że odwołujesz się do tab w chwili, gdy obiekt klasy TForm2 już nie istnieje.

0
0x666 napisał(a):

Zgaduję, że odwołujesz się do tab w chwili, gdy obiekt klasy TForm2 już nie istnieje.

Dlaczego miałby przestać istnieć?

0

Jak pisałem - zgaduje ;) Z kodu, który podałeś, niewiele da się wyciągnąć, jeśli chodzi o przyczynę błędu.

W Form1 mam wszystkie przyciski itp. (elementy wizualne)

Jeśli TForm1 jest główną formą, czym jest TForm2? Samo wywołanie TForm2::Wczytaj() powoduje błąd? Jak tworzysz obiekt klasy TForm2?

0
0x666 napisał(a):

Jak pisałem - zgaduje ;) Z kodu, który podałeś, niewiele da się wyciągnąć, jeśli chodzi o przyczynę błędu.

W Form1 mam wszystkie przyciski itp. (elementy wizualne)

Jeśli TForm1 jest główną formą, czym jest TForm2? Samo wywołanie TForm2::Wczytaj() powoduje błąd? Jak tworzysz obiekt klasy TForm2?

https://pastebin.com/059ZUtRw

Błąd powoduje prawdopodobnie ta linijka:

while (getline(plik, Linia)) tab.push_back(Linia);

Ale nie było z nią problemów kiedy istniała tylko jedna klasa.

0

Ta linia jest jak najbardziej ok. Nie widzę, żeby Form2 było tworzone (cały czas upieram się, że obiekt klasy TForm2 nie istnieje w czasie wywołania metody). Sprawdź, jaka jest wartość wskaźnika this wewnątrz TForm2::Wczytaj().

Jaki jest sens klasy TForm2, jeśli wszędzie odwołujesz się do Form1?

0
0x666 napisał(a):

Ta linia jest jak najbardziej ok. Nie widzę, żeby Form2 było tworzone (cały czas upieram się, że obiekt klasy TForm2 nie istnieje w czasie wywołania metody). Sprawdź, jaka jest wartość wskaźnika this wewnątrz TForm2::Wczytaj().

Jaki jest sens klasy TForm2, jeśli wszędzie odwołujesz się do Form1?

Więc jak stworzyć Form2?
Co do sensu klasy TForm2. Robię projekt na uczelnie. Kazał jak najwięcej klas, a nie wiem jak to zrobić bardziej estetyczniej. Oczywiście klasę TForm2 podziele jeszcze na dwie inne. na razie walczę z tym błędem.

0

Po pierwsze napisz nową klasę opisującą pytania.
Zgodnie z wzorcem MVC (Model View Controller), masz napisać klasę modelu danych, który przechowuje te dane.
TForm1 to twój kontroler, a widokiem są elementy UI-a, które wyklikałeś.

I jeszcze: https://4programmers.net/Forum/C_i_C++/300163-pytanie_o_strukture_danych_w_pliku_txt?p=1422976#id1422976 (pewnie kolega).

0
MarekR22 napisał(a):

Po pierwsze napisz nową klasę opisującą pytania.

Ale to mi nic nie da, bo i tak muszę się odwołać do TForm1, aby wskazać OpenDialog1.

Jak sprawdzić ten this?

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0