CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Kurs Praktyczny: Baza Danych, problem z klasa.cpp
Strona 1 z 1

Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 20:03
przez Tuzantar
Witam
Postanowiłem nauczyć się pisania BD, korzystając z poradnika http://programowanie.cal.pl/cyfbar/kurs2.html
korzystam z C++Builder 6
obecnie utknąłem w pkt 4.
skopiowałem do pliku klasa.cpp kod z http://programowanie.cal.pl/cyfbar/txt/klasacpp.txt
i po kliknięciu w F9 wyskakuje błąd:
Kod: Zaznacz cały
Build
  [C++ Error] klasa.cpp(215): E2316 'TDataBase::RefreshBase()' is not a member of 'TDataBase'


treść pliku klasa.cpp:
Kod: Zaznacz cały
//---------------------------------------------------------------------------


#pragma hdrstop

#include "klasa.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)
//---------------------------------------------------------------------------
TDataBase::TDataBase()
{   // konstruktor
Memo = new TStringList;
Bitmap = new TStringList;
}
//---------------------------------------------------------------------------
TDataBase::~TDataBase()
{   // destruktor
}
//---------------------------------------------------------------------------
String TDataBase::SetColSize(int Cols, TStringGrid *Grid)
{
String temp = "";
for(int i = 0; i < Cols; i++){
     temp = temp + IntToStr(Grid->ColWidths[i]) + "#";
                              }
     temp.Delete(temp.Length(), 1);
return temp;
}
//---------------------------------------------------------------------------
void TDataBase::GetColSize(String tekst, int Cols, TStringGrid *Grid)
{
int Cx;
for(int i = 0; i < Cols; i++){
     int x = tekst.LastDelimiter("#");
     try{Cx = (tekst.SubString(x + 1, 4)).ToInt();}catch(...){Cx = 60;}
     Grid->ColWidths[Cols - i - 1] = Cx;
     tekst.Delete(x, 4);
                              }
}
//---------------------------------------------------------------------------
void TDataBase::SaveToFile(String FileName, TStringGrid *Grid)
{
TStringList *Lista = new TStringList;

String temp1 = "", temp2;

for(int i = 0; i < Grid->RowCount; i++){
  for(int j = 0; j < Grid->ColCount; j++){
      if(Grid->Cells[j][i].IsEmpty())temp2 = "[EMPTY]";
      else temp2 = Grid->Cells[j][i];
      temp1 = temp1 + temp2 + "#";
                                         }
      temp1.Delete(temp1.Length(), 1);
      Lista->Add(temp1);
      temp1 = "";
                                        }
Lista->Add("[SECTION MEMO]");
for(int i = 0; i < Memo->Count; i++){
      Lista->Add(Memo->Strings[i]);
                                     }
for(int i = 0; i < Bitmap->Count; i++){
      Lista->Add(Bitmap->Strings[i]);
                                       }
Lista->Add(SetColSize(Grid->ColCount, Grid));
Lista->SaveToFile(FileName);
Lista->Free();
}
//---------------------------------------------------------------------------
int TDataBase::ObliczIleKolumn(String tekst)
{
int x = 0;
for(int i = 0; i < tekst.Length(); i++){
     x = (tekst.SubString(i, 1) == "#") ? x + 1 : x;
                                        }
return x + 1;
}
//---------------------------------------------------------------------------
int TDataBase::ObliczIleWierszy(TStringList *lista)
{
for(int i = 0; i < lista->Count; i++){
     if(lista->Strings[i] == "[SECTION MEMO]")
     return i;
                                      }
return lista->Count - 1;
}
//---------------------------------------------------------------------------
bool TDataBase::GetMemoSection(String tekst)
{
bool test = (tekst.SubString(1, 6) == "[MEMO]" ||
              tekst.SubString(1, 9) == "[BITMAPA]" ||
              tekst.SubString(1, 14) == "[SECTION MEMO]") ? true : false;
return test;
}
//---------------------------------------------------------------------------
void TDataBase::LoadFromFile(String FileName, TStringGrid *Grid)
{
TStringList *Lista = new TStringList;
Lista->LoadFromFile(FileName);
int x = ObliczIleKolumn(Lista->Strings[0]);
Grid->ColCount = x;
Grid->RowCount = ObliczIleWierszy(Lista);
GetColSize(Lista->Strings[Lista->Count - 1], x, Grid);

String temp;

for(int i = 0; i < Lista->Count - 1; i++){
  if(!GetMemoSection(Lista->Strings[i])){
   for(int j = 0; j < x; j++){
          int y = Lista->Strings[i].LastDelimiter("#");
             temp = Lista->Strings[i].SubString(y + 1, 1000);

          if(temp == "[EMPTY]")temp = "";
             Grid->Cells[x - j - 1][i] = temp;
             Lista->Strings[i] = Lista->Strings[i].Delete(y, 1000);
                             }
                                        }
  else {
        if(Lista->Strings[i].SubString(1, 6) == "[MEMO]")
            Memo->Add(Lista->Strings[i]);
        if(Lista->Strings[i].SubString(1, 9) == "[BITMAPA]")
            Bitmap->Add(Lista->Strings[i]);
       }
                                      }
Bitmap->SaveToFile("bitmapa.txt");
Lista->Free();
}
//---------------------------------------------------------------------------
void TDataBase::SetMemo(String tekst, int number)
{
String temp = "[MEMO]" + IntToStr(number) + "#";
int length = temp.Length();
bool test = false;
for(int i = 0; i < Memo->Count; i++){
if(Memo->Strings[i].SubString(1, length) == temp){
    Memo->Strings[i] = temp + tekst;
    test = true;
    break;
                                                  }
                                     }
if(!test)Memo->Add(temp + tekst);
}
//---------------------------------------------------------------------------
int TDataBase::WierszeMemo(String tekst)
{
int x = 0;
for(int i = 0; i < tekst.Length(); i++){
     x = (tekst.SubString(i, 1) == "|") ? x + 1 : x;
                                        }
return x;
}
//---------------------------------------------------------------------------
memo TDataBase::GetMemo(int number)
{
String temp;
memo zwrot;
int z;

for(int i = 0; i < Memo->Count; i++){
     temp = Memo->Strings[i].SubString(7, 1000);
     int x = temp.LastDelimiter("#");
     try{z = (temp.SubString(0, x - 1)).ToInt();}catch(...){z = 0;}
     if(z == number){
     temp = temp.Delete(1, x);
     break;
                    }
                                     }
if(z == number){
JestNotatka = true;
MemoCount = WierszeMemo(temp);

for(int i = 0; i < MemoCount; i++){
     int x = temp.LastDelimiter("|");
     zwrot.A[i] = (temp.SubString(x + 1, 1000));
     temp = temp.Delete(x, 1000);
                                           }
               } else JestNotatka = false;
return zwrot;
}
//---------------------------------------------------------------------------
void TDataBase::SetBitmap(String FileName, int number)
{
String temp = "[BITMAPA]" + IntToStr(number) + "#";
int length = temp.Length();
bool test = false;
for(int i = 0; i < Bitmap->Count; i++){
if(Bitmap->Strings[i].SubString(1, length) == temp){
    Bitmap->Strings[i] = temp + FileName;
    test = true;
    break;
                                                    }
                                     }
if(!test)Bitmap->Add(temp + FileName);
}
//---------------------------------------------------------------------------
String TDataBase::GetBitmap(int number)
{
String temp = "";
int z;

for(int i = 0; i < Bitmap->Count; i++){
     temp = Bitmap->Strings[i].SubString(10, 300);
     int x = temp.LastDelimiter("#");
     try{z = (temp.SubString(1, x - 1)).ToInt();}catch(...){z = 0;}
     if(z == number){
     temp = temp.Delete(1, x);
     return temp;
                    }
                                     }
return temp;
}
//---------------------------------------------------------------------------
void TDataBase::RefreshBase(void)
{
Bitmap->Clear();
Memo->Clear();
}
//---------------------------------------------------------------------------


jakieś pomysły co robię nie tak??

=======================================
P.S. prawdopodobnie będę miał jeszcze wiele innych błędów więc będę kontynuował w tym temacie

Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 20:19
przez Cyfrowy Baron
Problem polega na tym, że plikowi CPP niemal zawsze towarzyszy plik H. Ty utworzyłeś własny plik CPP w oparciu o zawartość pliku tekstowego stąd błędy. Brakuje tego, co znajduje się w pliku H. Na końcu kursu masz pliki źródłowe do pobrania - pobierz je. W archiwum znajdziesz dwa pliki klasa.h i klasa.cpp. Musisz dołączyć do projektu plik klasa.h poprzez menu: Project -> Add toi project.
To przykład bardzo prymitywnej bazy danych i pomimo mylącej nazwy TDataBase nie jest to przykład oparty na BDE ani żadnym innym silniku bazodanowym.

Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 20:38
przez Tuzantar
tylko ze mam klasa.h (zrobiony w 2 i 3 pkt)
Kod: Zaznacz cały
//---------------------------------------------------------------------------
#include <Grids.hpp>
#ifndef klasaH
#define klasaH
//---------------------------------------------------------------------------
struct memo
{
   String A[1000];
};
//---------------------------------------------------------------------------
class TDataBase
{
public:
TDataBase();
~TDataBase();

void SaveToFile(String FileName, TStringGrid *Grid);
void LoadFromFile(String FileName, TStringGrid *Grid);
void SetMemo(String tekst, int number);
void SetBitmap(String FileName, int number);
memo GetMemo(int number);
String GetBitmap(int number);

int MemoCount;
bool JestNotatka;

private:
int ObliczIleKolumn(String tekst);
int ObliczIleWierszy(TStringList *lista);

String SetColSize(int Cols, TStringGrid *Grid);
void GetColSize(String tekst, int Cols, TStringGrid *Grid);

bool GetMemoSection(String tekst);
int WierszeMemo(String tekst);

TStringList *Memo;
TStringList *Bitmap;
};
//---------------------------------------------------------------------------
#endif

ale spróbuję podmienić

podmieniłem klasa.h razem z klasa.cpp i już nie wyrzuca błędu, widocznie musiałem gdzieś coś źle przepisać

Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 20:53
przez Cyfrowy Baron
Wszystko zależy jak to robisz i czy włączyłeś plik klasa.h do projektu poprzez menu: Project - Add to project, potem wybierasz plik klasa.h i gotowe. pozostaje jeszcze dodanie w pliku nagłówkowym aplikacji w sekcji include dodanie #include "klasa.h". To są takie podstawowe spawy, że aż się dziwię iż ktoś jeszcze o to pyta.
Pliki klasa.cpp i klasa.h też nie tworzysz w notatniku, lecz najlepiej jest je pobrać ze strony i skopiować do katalogu projektu. Jeżeli chcesz je stworzyć sam. To po utworzeniu projektu wybierasz z menu: File -> New -> Unit C++Builder. Zostaną utworzone dwa pliki Unit1.cpp i Unit1.h zapisujesz je w katalogu projektu np. pod nazwą klasa. Przy takim tworzeniu plików nie musisz dodawać ich poprzez menu: Project -> Add to project, gdyż są dodawane automatycznie. Potem wypełniasz pliki kodem, ale nie usuwasz tego co już tam jest tylko dodajesz nowe funkcje, zmienne, klasy itp.

Proponuje byś zapoznał się z kursem: teoria -> Tworzenie klas; oraz: teoria -> Tworzenie modułów.

To tyle gwoli wyjaśnienia, ale pozostaje jeszcze kwestia błędu. Tutaj ja popełniłem błąd w kursie, gdyż nie dodałem deklaracji funkcji RefreshBase w pliku nagłówkowym klasa.h.


Klasa.h:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------
#ifndef KlasaH
#define KlasaH
//---------------------------------------------------------------------------
#include <Grids.hpp>
//---------------------------------------------------------------------------
struct memo
{
 String A[1000];
};
//---------------------------------------------------------------------------
class TDataBase
{
 public:
 TDataBase();
 ~TDataBase();

 void SaveToFile(String FileName, TStringGrid *Grid);
 void LoadFromFile(String FileName, TStringGrid *Grid);
 void SetMemo(String tekst, int number);
 void SetBitmap(String FileName, int number);
 void RefreshBase(void);                                                     // <-- tego zabrakło
 memo GetMemo(int number);
 String GetBitmap(int number);

 int MemoCount;
 bool JestNotatka;

 private:
 int ObliczIleKolumn(String tekst);
 int ObliczIleWierszy(TStringList *lista);

 String SetColSize(int Cols, TStringGrid *Grid);

 void GetColSize(String tekst, int Cols, TStringGrid *Grid);
 bool GetMemoSection(String tekst);
 int WierszeMemo(String tekst);

 TStringList *Memo;
 TStringList *Bitmap;
 
};
//---------------------------------------------------------------------------
#endif


Klasa.cpp
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Klasa.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
TDataBase::TDataBase()
{   // konstruktor
 Memo = new TStringList;
 Bitmap = new TStringList;
}
//---------------------------------------------------------------------------
TDataBase::~TDataBase()
{   // destruktor
}
//---------------------------------------------------------------------------
String TDataBase::SetColSize(int Cols, TStringGrid *Grid)
{
 String temp = "";
 for(int i = 0; i < Cols; i++){
     temp = temp + IntToStr(Grid->ColWidths[i]) + "#";
                              }
     temp.Delete(temp.Length(), 1);
 return temp;
}
//---------------------------------------------------------------------------
void TDataBase::GetColSize(String tekst, int Cols, TStringGrid *Grid)
{
 int Cx;
 for(int i = 0; i < Cols; i++){
     int x = tekst.LastDelimiter("#");
     try{Cx = (tekst.SubString(x + 1, 4)).ToInt();}catch(...){Cx = 60;}
     Grid->ColWidths[Cols - i - 1] = Cx;
     tekst.Delete(x, 4);
                              }
}
//---------------------------------------------------------------------------
void TDataBase::SaveToFile(String FileName, TStringGrid *Grid)
{
 TStringList *Lista = new TStringList;

 String temp1 = "", temp2;

 for(int i = 0; i < Grid->RowCount; i++){
  for(int j = 0; j < Grid->ColCount; j++){
      if(Grid->Cells[j][i].IsEmpty())temp2 = "[EMPTY]";
      else temp2 = Grid->Cells[j][i];
      temp1 = temp1 + temp2 + "#";
                                         }
      temp1.Delete(temp1.Length(), 1);
      Lista->Add(temp1);
      temp1 = "";
                                        }
 Lista->Add("[SECTION MEMO]");
 for(int i = 0; i < Memo->Count; i++){
      Lista->Add(Memo->Strings[i]);
                                     }
 for(int i = 0; i < Bitmap->Count; i++){
      Lista->Add(Bitmap->Strings[i]);
                                       }
 Lista->Add(SetColSize(Grid->ColCount, Grid));
 Lista->SaveToFile(FileName);
 Lista->Free();
}
//---------------------------------------------------------------------------
int TDataBase::ObliczIleKolumn(String tekst)
{
 int x = 0;
 for(int i = 0; i < tekst.Length(); i++){
     x = (tekst.SubString(i, 1) == "#") ? x + 1 : x;
                                        }
 return x + 1;
}
//---------------------------------------------------------------------------
int TDataBase::ObliczIleWierszy(TStringList *lista)
{
 for(int i = 0; i < lista->Count; i++){
     if(lista->Strings[i] == "[SECTION MEMO]")
     return i;
                                      }
 return lista->Count - 1;
}
//---------------------------------------------------------------------------
bool TDataBase::GetMemoSection(String tekst)
{
 bool test = (tekst.SubString(1, 6) == "[MEMO]" ||
              tekst.SubString(1, 9) == "[BITMAPA]" ||
              tekst.SubString(1, 14) == "[SECTION MEMO]") ? true : false;
 return test;
}
//---------------------------------------------------------------------------
void TDataBase::LoadFromFile(String FileName, TStringGrid *Grid)
{
 TStringList *Lista = new TStringList;
 Lista->LoadFromFile(FileName);
 int x = ObliczIleKolumn(Lista->Strings[0]);
 Grid->ColCount = x;
 Grid->RowCount = ObliczIleWierszy(Lista);
 GetColSize(Lista->Strings[Lista->Count - 1], x, Grid);

 String temp;

 for(int i = 0; i < Lista->Count - 1; i++){
  if(!GetMemoSection(Lista->Strings[i])){
   for(int j = 0; j < x; j++){
          int y = Lista->Strings[i].LastDelimiter("#");
             temp = Lista->Strings[i].SubString(y + 1, 1000);

          if(temp == "[EMPTY]")temp = "";
             Grid->Cells[x - j - 1][i] = temp;
             Lista->Strings[i] = Lista->Strings[i].Delete(y, 1000);
                             }
                                        }
  else {
        if(Lista->Strings[i].SubString(1, 6) == "[MEMO]")
            Memo->Add(Lista->Strings[i]);
        if(Lista->Strings[i].SubString(1, 9) == "[BITMAPA]")
            Bitmap->Add(Lista->Strings[i]);
       }
                                      }
 Bitmap->SaveToFile("bitmapa.txt");
 Lista->Free();
}
//---------------------------------------------------------------------------
void TDataBase::SetMemo(String tekst, int number)
{
 String temp = "[MEMO]" + IntToStr(number) + "#";
 int length = temp.Length();
 bool test = false;
 for(int i = 0; i < Memo->Count; i++){
 if(Memo->Strings[i].SubString(1, length) == temp){
    Memo->Strings[i] = temp + tekst;
    test = true;
    break;
                                                  }
                                     }
 if(!test)Memo->Add(temp + tekst);
}
//---------------------------------------------------------------------------
int TDataBase::WierszeMemo(String tekst)
{
 int x = 0;
 for(int i = 0; i < tekst.Length(); i++){
     x = (tekst.SubString(i, 1) == "|") ? x + 1 : x;
                                        }
 return x;
}
//---------------------------------------------------------------------------
memo TDataBase::GetMemo(int number)
{
 String temp;
 memo zwrot;
 int z;

 for(int i = 0; i < Memo->Count; i++){
     temp = Memo->Strings[i].SubString(7, 1000);
     int x = temp.LastDelimiter("#");
     try{z = (temp.SubString(0, x - 1)).ToInt();}catch(...){z = 0;}
     if(z == number){
     temp = temp.Delete(1, x);
     break;
                    }
                                     }
 if(z == number){
 JestNotatka = true;
 MemoCount = WierszeMemo(temp);

 for(int i = 0; i < MemoCount; i++){
     int x = temp.LastDelimiter("|");
     zwrot.A[i] = (temp.SubString(x + 1, 1000));
     temp = temp.Delete(x, 1000);
                                           }
               } else JestNotatka = false;
 return zwrot;
}
//---------------------------------------------------------------------------
void TDataBase::SetBitmap(String FileName, int number)
{
 String temp = "[BITMAPA]" + IntToStr(number) + "#";
 int length = temp.Length();
 bool test = false;
 for(int i = 0; i < Bitmap->Count; i++){
 if(Bitmap->Strings[i].SubString(1, length) == temp){
    Bitmap->Strings[i] = temp + FileName;
    test = true;
    break;
                                                    }
                                     }
 if(!test)Bitmap->Add(temp + FileName);
}
//---------------------------------------------------------------------------
String TDataBase::GetBitmap(int number)
{
 String temp = "";
 int z;

 for(int i = 0; i < Bitmap->Count; i++){
     temp = Bitmap->Strings[i].SubString(10, 300);
     int x = temp.LastDelimiter("#");
     try{z = (temp.SubString(1, x - 1)).ToInt();}catch(...){z = 0;}
     if(z == number){
     temp = temp.Delete(1, x);
     return temp;
                    }
                                     }
 return temp;
}
//---------------------------------------------------------------------------
void TDataBase::RefreshBase(void)
{
 Bitmap->Clear();
 Memo->Clear();
}
//---------------------------------------------------------------------------

Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 21:01
przez Tuzantar
Robię wg kolejności w poradniku i jak na razie wszystko jest ok :) (no oprócz tego RefreshBase, ale dzięki Tobie problem zażegnany)
Wracam do pisania :)

Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 21:07
przez Cyfrowy Baron
Nie cytuj całych postów, przecież wiadomo o czym dyskutujemy. Jeżeli chcesz się odnieść do jakiegoś fragmentu wypowiedzi to zacytuj ten fragment. Jeżeli odnosisz się do całego postu, to nic nie cytuj.

Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 21:37
przez Tuzantar
no i mam kolejny błąd (ale chyba ostatni)
po kliknięciu w F9, wyskakuje:


[Linker Error] Unresolved external '__fastcall TForm1::StringGrid1Click(System::TObject *)' referenced from D:\BCBPROBNY\BDMP BORLAND\UNIT1.OBJ


Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 21:54
przez Cyfrowy Baron
Mam pewne podjerzenia. Opisz dokładnie jak utworzyłeś zdarzenie OnClick dla obiektu StringGrid1.

Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 21:59
przez Tuzantar
no właśnie problem w tym że nie tworzyłem takiego zdarzenia, tylko OnSelectCell
klik na StringGrid1 Events->dwuklik na OnSelectCell i wpisałem kod z poradnika
KOD cpp:     UKRYJ  
void __fastcall TForm1::StringGrid1SelectCell(TObject *Sender, int ACol,
      int ARow, bool &CanSelect)
{
 Memo1->Clear();
  memo temp; //definicja struktury memo
  temp = Baza->GetMemo(ARow);
  if(Baza->JestNotatka)
    {
      for(int i = 0; i < Baza->MemoCount; i++){
        if(!temp.A[Baza->MemoCount - i - 1].IsEmpty())
         Memo1->Lines->Add(temp.A[Baza->MemoCount - i - 1]);
              }
    }

  Image1->Picture = NULL;
  try{Image1->Picture->LoadFromFile(Baza->GetBitmap(ARow));}
  catch(...){;}
}

a okienko StringGrid1 Events->OnClick jest puste

Re: Kurs Praktyczny: Baza Danych, problem z klasa.cpp

Nowy postNapisane: poniedziałek, 6 grudnia 2010, 23:36
przez Cyfrowy Baron
Trudno powiedzieć co Ty tam nawyczyniałeś. Sprawdź czy w pliku nagłówkowym formularza masz deklarację zdarzenie StringGrid1Click i czy masz definicję tego zdarzenia w pliku źródłowym.

Najlepiej wrzuć ten projekt na forum. Odnoszę wrażenie, że masz znikome pojęcie o środowisku C++Builder.