C++ Builder Wczytywanie Tabeli - błąd po kompilacji

0

Witajcie.

Na początku chciałbym Wam powiedzieć, że zaczynam przygodę z C++ builder, korzystałem z serwisu (nie wiem czy moge zamieścić link), twórcą jest Cyfbar. Chciałem, aby informacje z tabeli którą stworzyłem zostały zapisane do pliku, a po kliknięciu przycisku został ten plik wczytany. W poradniku było ładnie wszystko napisane. Program kompiluje się dobrze, lecz po wybraniu buttonu z ładowaniem pliku wyskakuje " is not a valid integer value oraz pokazuje na linijkę:

 Grid->ColCount = txt_1.SubString(5, txt_1.Length() - 5).ToInt();

jeżeli usunę tą linijkę lub podstawie 0 to pokazuje następną linijkę:

 Grid->RowCount = txt_2.SubString(5, txt_2.Length() - 5).ToInt();

Jeżeli również to podstawie do 0 to pokazuje kolejną linijkę:

Size = txt_2.ToInt();

Tutaj jeżeli dam zero, to niby ładuje plik, lecz po prostu usuwa tabele.

Dodam jeszcze, że są tam jeszcze 3 przyciski - dodanie kolumny, wiersza, oraz zapis - te 3 działają poprawnie.
Kod zamieszczam poniżej.


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

#include <vcl.h>
#pragma hdrstop

#include "trol.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------
 void __fastcall SaveGridToFile(AnsiString FileName, TStringGrid *Grid,
        bool csv)
{

 TStringList *Lista = new TStringList;
 AnsiString txt_1 = "", txt_2 = "";

 if(!csv)
 Lista->Add("\"Col" + (AnsiString)Grid->ColCount + "\";\"ROW" + (AnsiString)Grid->RowCount + "\"");

 for(int i = 0; i < Grid->RowCount; i++)
 {
  for(int j = Grid->ColCount - 1; j >= 0; j--)
  {
   String temp = Grid->Cells[j][i];
   if(temp.SubString(temp.Length(), temp.Length() + 1) == ";")
    temp = Grid->Cells[j][i] + "'";
   if(!csv)
    txt_1 = ";\"" + temp + "\"" + txt_1;
   else
    txt_1 = "\"" + temp + "\";" + txt_1;

   if(!csv && i == 0)
   {
    txt_2 = (AnsiString)Grid->ColWidths[j] + ";" + txt_2;
    if(j == 0)
    Lista->Add(txt_2);
   }
  }
  Lista->Add(txt_1);
  txt_1 = "";
 }

 Lista->SaveToFile(FileName);
 delete Lista;
}
void SetColRow(AnsiString txt, TStringGrid *Grid)
{

 int t = txt.AnsiPos("\";");
 AnsiString txt_1 = txt.SubString(1, t);
 AnsiString txt_2 = txt.SubString(t + 2, 10);
 Grid->ColCount = txt_1.SubString(5, txt_1.Length() - 5).ToInt();
 Grid->RowCount = txt_2.SubString(5, txt_2.Length() - 5).ToInt();

}

//--- FUNKCJA PRZEPISUJĄCA TEKST DO KOMÓREK I ODCZYUJĄCA SZEROKOŚĆ KOLUMN ---
AnsiString SetCellText(AnsiString txt, AnsiString Wtxt, int &Size, int Col)
{
 String txt_1 = "", txt_2 = "";
 for(int i = -1; i < Col; i++)
 {
  int q = 0;
  int t = txt.AnsiPos(";\"");
  if(i >= 0)
   q = Wtxt.AnsiPos(";");
  txt_1 = txt.SubString(2, t - 3);
  if(i >= 0)
   txt_2 = Wtxt.SubString(1, q - 1);

  if(t > 0)
   txt = txt.Delete(1, t);
  else
   txt_1 = txt.SubString(2, txt.Length() - 2);

  if(i >= 0)
  {
   if(q > 0)
    Wtxt = Wtxt.Delete(1, q);
   else
    txt_2 = Wtxt.SubString(1, Wtxt.Length() - 1);
  }
 }
 Size = txt_2.ToInt();
 if(txt_1.SubString(txt_1.Length() - 1, txt_1.Length() + 1) == ";'")
  txt_1 = txt_1.Delete(txt_1.Length(), txt_1.Length() + 1);

 return txt_1;
}
//--- FUNKCJA ODCZYTUJÄ„CA TABELÄ  Z PLIKU ------------------------------------
void __fastcall LoadGridFromFile(AnsiString FileName, TStringGrid *Grid)
{
 TStringList *Lista = new TStringList;
 Lista->LoadFromFile(FileName);
 SetColRow(Lista->Strings[0], Grid);

 for(int i = 0; i < Grid->RowCount; i++)
 {
  for(int j = 0; j < Grid->ColCount; j++)
  {
   int Size;
   Grid->Cells[j][i] = SetCellText(Lista->Strings[i + 2], Lista->Strings[1], Size, j + 1);
   Grid->ColWidths[j] = Size;
  }
 }
 delete Lista;
}

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

enum TAddColRow {crCol, crRow};
void __fastcall AddColRow(TStringGrid *Grid, TAddColRow crAdd)
{
 switch(crAdd)
 {
  case crRow: Grid->RowCount++;
              for(int i = Grid->RowCount - 1; i >= Grid->Row + 1; i--)
              {
               for(int j = 0; j < Grid->ColCount; j++)
               {
                if(i == Grid->Row + 1) Grid->Cells[j][Grid->Row + 1] = "";
                else Grid->Cells[j][i] = Grid->Cells[j][i - 1];
               }
              }
              return;
  case crCol: Grid->ColCount++;
              for(int i = Grid->ColCount - 1; i >= Grid->Col + 1; i--)
              {
               for(int j = 0; j < Grid->RowCount; j++)
               {
                if(i == Grid->Col + 1)
                {
                 Grid->Cells[Grid->Col + 1][j] = "";
                 Grid->ColWidths[Grid->Col + 1] = Grid->ColWidths[Grid->Col];
                }
                else
                {
                 Grid->Cells[i][j] = Grid->Cells[i - 1][j];
                 Grid->ColWidths[i] = Grid->ColWidths[i - 1];
                }
               }
              }
              return;
 }
}


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



void __fastcall TForm3::Button3Click(TObject *Sender)
{
   SaveGridToFile("Nazwa_pliku.csv", StringGrid1, true);      
}
//---------------------------------------------------------------------------

void __fastcall TForm3::Button4Click(TObject *Sender)
{
  LoadGridFromFile("Nazwa_pliku.csv", StringGrid1);
}
//---------------------------------------------------------------------------

void __fastcall TForm3::Button1Click(TObject *Sender)
{
AddColRow(StringGrid1, crCol); // wstawianie kolumny
}
//---------------------------------------------------------------------------

void __fastcall TForm3::Button2Click(TObject *Sender)
{
    AddColRow(StringGrid1, crRow); // wstawianie wiersza
}
//---------------------------------------------------------------------------



void __fastcall TForm3::FormCreate(TObject *Sender)
{
LoadGridFromFile("Nazwa_pliku.csv", StringGrid1);        
}
//---------------------------------------------------------------------------

Z góry dziękuję za okazaną pomoc.
Pozdrawiam serdecznie, Michał

0

A wstać na ten wiersz breakpointem i zobaczyć jaka wartość txt_1?

0

Mógłbyś dokładniej napisać, co masz na myśli, jak pisałem na początku zaczynam dopiero przygodę i nie za bardzo wiem co masz na mysli.

Edit:

Ok, wiem o co chodzi - z debugowania, lecz nie wiem, jak sprawdzić wartość tej zmiennej. Prosiłbym o jakieś wytłumaczenie.

Pozdrawiam

Edit 2:

Pokombinowałem i błąd wyskakuje mi 2 linijki wyżej na:

 String txt_1 = txt.SubString(1, t);

Poniżej wklejam kod, który mam teraz

błąd który teraz wyskakuje w tej linijce:

{"\x11''"}

kod:

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

#include <vcl.h>
#pragma hdrstop

#include "trol.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------
 void __fastcall SaveGridToFile(AnsiString FileName, TStringGrid *Grid,
        bool csv)
{

 TStringList *Lista = new TStringList;
String txt_1 = "", txt_2 = "";

 if(!csv)
 Lista->Add("\"Col" + (AnsiString)Grid->ColCount + "\";\"ROW" + (AnsiString)Grid->RowCount + "\"");

 for(int i = 0; i < Grid->RowCount; i++)
 {
  for(int j = Grid->ColCount - 1; j >= 0; j--)
  {
   String temp = Grid->Cells[j][i];
   if(temp.SubString(temp.Length(), temp.Length() + 1) == ";")
    temp = Grid->Cells[j][i] + "'";
   if(!csv)
    txt_1 = ";\"" + temp + "\"" + txt_1;
   else
    txt_1 = "\"" + temp + "\";" + txt_1;

   if(!csv && i == 0)
   {
    txt_2 = (AnsiString)Grid->ColWidths[j] + ";" + txt_2;
    if(j == 0)
    Lista->Add(txt_2);
   }
  }
  Lista->Add(txt_1);
  txt_1 = "";
 }

 Lista->SaveToFile(FileName);
 delete Lista;
}
void SetColRow(AnsiString txt, TStringGrid *Grid)
{

 int t = txt.AnsiPos("\";");
String txt_1 = txt.SubString(1, t);
String txt_2 = txt.SubString(t + 2, 10);
 Grid->ColCount = txt_1.SubString(5, txt_1.Length() - 5).ToInt();
 Grid->RowCount = txt_2.SubString(5, txt_2.Length() - 5).ToInt();

}

//--- FUNKCJA PRZEPISUJĄCA TEKST DO KOMÓREK I ODCZYUJĄCA SZEROKOŚĆ KOLUMN ---
AnsiString SetCellText(AnsiString txt, AnsiString Wtxt, int &Size, int Col)
{
 String txt_1 = "", txt_2 = "";
 for(int i = -1; i < Col; i++)
 {
  int q = 0;
  int t = txt.AnsiPos(";\"");
  if(i >= 0)
   q = Wtxt.AnsiPos(";");
  txt_1 = txt.SubString(2, t - 3);
  if(i >= 0)
   txt_2 = Wtxt.SubString(1, q - 1);

  if(t > 0)
   txt = txt.Delete(1, t);
  else
   txt_1 = txt.SubString(2, txt.Length() - 2);

  if(i >= 0)
  {
   if(q > 0)
    Wtxt = Wtxt.Delete(1, q);
   else
    txt_2 = Wtxt.SubString(1, Wtxt.Length() - 1);
  }
 }
 Size = txt_2.ToInt();
 if(txt_1.SubString(txt_1.Length() - 1, txt_1.Length() + 1) == ";'")
  txt_1 = txt_1.Delete(txt_1.Length(), txt_1.Length() + 1);

 return txt_1;
}
//--- FUNKCJA ODCZYTUJĄCA TABELĘ Z PLIKU ------------------------------------
void __fastcall LoadGridFromFile(AnsiString FileName, TStringGrid *Grid)
{
 TStringList *Lista = new TStringList;
 Lista->LoadFromFile(FileName);
 SetColRow(Lista->Strings[0], Grid);

 for(int i = 0; i < Grid->RowCount; i++)
 {
  for(int j = 0; j < Grid->ColCount; j++)
  {
   int Size;
   Grid->Cells[j][i] = SetCellText(Lista->Strings[i + 2], Lista->Strings[1], Size, j + 1);
   Grid->ColWidths[j] = Size;
  }
 }
 delete Lista;
}

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

enum TAddColRow {crCol, crRow};
void __fastcall AddColRow(TStringGrid *Grid, TAddColRow crAdd)
{
 switch(crAdd)
 {
  case crRow: Grid->RowCount++;
              for(int i = Grid->RowCount - 1; i >= Grid->Row + 1; i--)
              {
               for(int j = 0; j < Grid->ColCount; j++)
               {
                if(i == Grid->Row + 1) Grid->Cells[j][Grid->Row + 1] = "";
                else Grid->Cells[j][i] = Grid->Cells[j][i - 1];
               }
              }
              return;
  case crCol: Grid->ColCount++;
              for(int i = Grid->ColCount - 1; i >= Grid->Col + 1; i--)
              {
               for(int j = 0; j < Grid->RowCount; j++)
               {
                if(i == Grid->Col + 1)
                {
                 Grid->Cells[Grid->Col + 1][j] = "";
                 Grid->ColWidths[Grid->Col + 1] = Grid->ColWidths[Grid->Col];
                }
                else
                {
                 Grid->Cells[i][j] = Grid->Cells[i - 1][j];
                 Grid->ColWidths[i] = Grid->ColWidths[i - 1];
                }
               }
              }
              return;
 }
}


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



void __fastcall TForm3::Button3Click(TObject *Sender)
{
   SaveGridToFile("Nazwa_pliku.csv", StringGrid1, true);      
}
//---------------------------------------------------------------------------

void __fastcall TForm3::Button4Click(TObject *Sender)
{
  LoadGridFromFile("Nazwa_pliku.csv", StringGrid1);
}
//---------------------------------------------------------------------------

void __fastcall TForm3::Button1Click(TObject *Sender)
{
AddColRow(StringGrid1, crCol); // wstawianie kolumny
}
//---------------------------------------------------------------------------

void __fastcall TForm3::Button2Click(TObject *Sender)
{
    AddColRow(StringGrid1, crRow); // wstawianie wiersza
}
//---------------------------------------------------------------------------



0

Zgodnie z Twoimi poradami:

zmienna txt_1: "txt_1: { "\"sa\"" } "
nie wiem czy dobrze kombinowałem, ale przejrzałem jeszcze

SubString(5, txt_1.Length() - 5).ToInt()

pokazuje mi : E2268 Call to undefined function 'SubString'

Co można z tym fantem zrobić ?

ps. sorry za offtopa.

0

SubString() to funkcja składowa klasy AnsiString. Możesz ją wywołać tylko na rzecz obiektu typu AnsiString.

Ogólnie radzę zapomnieć o tym kodzie. No, może poza funkcją AddColRow(). Poniżej trzy funkcje robiące to samo:

void SaveGridToFile(AnsiString FileName, TStringGrid *Grid)
{
    TStringList *File = new TStringList;
    //zapisuje liczbę wierszy i kolumn (w podobny sposób można zapisać inne informacje o tabeli)
    File->Append("Rows=" + IntToStr(Grid->RowCount));
    File->Append("Cols=" + IntToStr(Grid->ColCount));
    File->Append("[DATA]");//znacznik początku danych
    for(int i = 0; i < Grid->RowCount; ++i)
        File->Append(Grid->Rows[i]->CommaText);//zapisuje cały wiersz (rekord) w jednej linii.

    File->SaveToFile(FileName);
    delete File;
}

void LoadGridFromFile(AnsiString FileName, TStringGrid *Grid)
{
    TStringList *File = new TStringList;

    File->LoadFromFile(FileName);
    //ustala potrzebną liczbę wierszy i kolumn
    Grid->RowCount = StrToInt(File->Values["Rows"]);
    Grid->ColCount = StrToInt(File->Values["Cols"]);
    
    for(int i = File->IndexOf("[DATA]") + 1, r = 0; i < File->Count; ++i, ++r)
        Grid->Rows[r]->CommaText = File->Strings[i];//wczytuje cały wiersz (rekord)

    delete File;
}

void LoadGridFromCSVFile(AnsiString FileName, TStringGrid *Grid)
{
    TStringList *File = new TStringList;
    TStringList *Record = new TStringList;
    File->LoadFromFile(FileName);
    Grid->RowCount = File->Count;//liczba wierszy odpowiada liczbie linii
    Grid->ColCount = 1;//minimalna liczba kolumn (musi być o 1 większa od FixedCols!)

    for(int i = 0; i < File->Count; ++i)
    {
        Record->Text = AnsiReplaceStr(File->Strings[i], ";", "\n");
        //na wypadek gdyby poszczególne wiersze zawierały różną liczbę kolumn
        if(Grid->ColCount < Record->Count)
            Grid->ColCount = Record->Count;
        
        Grid->Rows[i]->Assign(Record);//wczytuje cały wiersz (rekord)
    }
    delete File;
    delete Record;
}
 

Co zawiera CommaText, Values[] oraz co robią IndexOf() i Assign() klasy TStringList oraz AnsiReplaceStr() dowiesz się w pomocy do C++ Buildera.
Ostatnia z wymienionych funkcji może wymagać dołączenia pliku "StrUtils.hpp".

0

@Rekman Wielkie dzięki ! poradziłem sobie z tym.

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