CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Dzielenie tekstu...

Dzielenie tekstu...

dział ogólny

Dzielenie tekstu...

Nowy postprzez Przemyslav » piątek, 28 października 2016, 21:23

Witam wszystkich bardzo serdecznie. Mam problem z dzieleniem zawartości pliku i jego poprawnym wyświetlaniem.

Mam plik tekstowy np. test.txt o zawartości:

Kod: Zaznacz cały
230,818 - 232,541 km=Powiat Włocławski, Gmina Krzyżanówek
237,358 - 264,801 km=Powiat Gostyniński, Gmina Ablacja
316,478 - 334,432 km=Powiat Kutnowski, Gmina Ręczno
itd...


Kolejne linijki wczytuję osobno, tekst z lewej strony a z prawej pd znaku "=" umiem rozdzielić dzięki np.
KOD cpp:     UKRYJ  
Memo1->Lines->Append(Lista->Values[Lista->Names[RadioGroup1->ItemIndex]]);
ale jak zrobić aby np. tekst "Powiat Włocławski," oraz tekst "Gmina Krzyżanówek" ponownie rozdzielić tak, aby każde z nich, aby wyświetlało się w innym Labelu jako Caption? Próbuję z LastDelimiter, ale ucina nie to co trzeba.
Tekst typu Powiat i Gmina to stałe słowa - są zawsze, jednak ich położenie jest różne z uwagi na inną długość nazw powiatów i gmin.

EDIT: Udało się wydzielić gminę przy tekście:
Kod: Zaznacz cały
Powiat Kutnowski\\Gmina Zgierski


i kodzie:

KOD cpp:     UKRYJ  
int index = powiatgmina.LastDelimiter("\\");
powiatgmina.Delete(1, index);
powiat->Caption = powiatgmina;


Teraz nie wiem jak pozyskać powiat.
Ostatnio edytowano sobota, 29 października 2016, 18:57 przez Przemyslav, łącznie edytowano 1 raz
Avatar użytkownika
Przemyslav
Bladawiec
Bladawiec
 
Posty: 42
Dołączył(a): niedziela, 25 maja 2014, 13:59
Podziękował : 22
Otrzymał podziękowań: 0
System operacyjny: Windows 10 x64
Kompilator: C++ Builder 6
Gadu Gadu: 0
    WindowsFirefox

Re: Dzielenie tesktu...

Nowy postprzez Cyfrowy Baron » sobota, 29 października 2016, 09:59

Zakładam, że ten obiekt Lista jest typu TStrings lub TWideStrings, gdyż inaczej ten twój kod by nie działał. Domyślnie jako separatora obiekt używa znaku równości, więc używając metod Values i Names dzielisz tekst na dwie części pomiędzy znakiem równości. Klasa TStrings i TWideStrings posiada jednak jeszcze metodę NameValueSeparator, której to metodzie możesz przypisać inny sperarator i znów dzielić tekst za pomocą metod Values i Names. Nazwy miejscowości masz na liście rozdzielone przecinkiem, możesz więc ustawić jako separator przecinek i znów dzielić.

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

#include "Unit1.h"
#include <memory>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

using namespace std;

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 auto_ptr<TStrings> Lista(new TStringList); // Lista tymczasowa typu TStringList

 Lista->Add("230,818 - 232,541 km=Powiat Włocławski, Gmina Krzyżanówek");
 Lista->Add("237,358 - 264,801 km=Powiat Gostyniński, Gmina Ablacja");

 int i = 0;
 while( i < Lista->Count )
 {
  ListBoxNames->Items->Add( Lista->Names[i++] ); // Lista TListBox
 }

 i = 0;
 while( i < Lista->Count  )
 {
  ListBoxValues->Items->Add( Lista->Values[Lista->Names[i++]] ); // Lista TListBox
 }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBoxValuesClick(TObject *Sender)
{
 int iSelect = ListBoxValues->ItemIndex; // Lista TListBox

 ListBoxValues->Items->NameValueSeparator = ','; // Lista TListBox

 LabelPowiat->Caption = ListBoxValues->Items->Names[iSelect]; // TLabel

 LabelGmina->Caption = ListBoxValues->Items->ValueFromIndex[iSelect].Trim(); // TLabel

}
//---------------------------------------------------------------------------
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Dzielenie tesktu...

Nowy postprzez Przemyslav » sobota, 29 października 2016, 18:46

Coś nie działa kod:

KOD cpp:     UKRYJ  
[C++ Error] Unit1.cpp(1019): E2451 Undefined symbol 'ListBoxNames'
[C++ Error] Unit1.cpp(1025): E2451 Undefined symbol 'ListBoxValues'


Próbowałem w swoim projekcie, jak i na czystym projekcie. Używam Borlanda w wersji 6.0.

Aktualnie w projekcie mam tak:

1. Wnętrze przykładowego pliku "kraj92pik.dat" z danymi wygląda tak:

Kod: Zaznacz cały
...
305,700 - 316,478 km=Miasto Łódź
316,478 - 334,432 km=Powiat Łódzki Wschodni
382,333 - 385,263 km=Powiat Łódzki Wschodni
385,263 - 386,139 km=Powiat Piotrkowski
386,139 - 386,518 km=Powiat Łódzki Wschodni
386,518 - 399,837 km=Powiat Piotrkowski
...


2. Plik Unit1.h ma deklarację listy:

KOD cpp:     UKRYJ  
private:        // User declarations
        THashedStringList *Lista;


3. Następnie na formie mam ComboBox, RadioGroup i zwykły Label.

4. I tak w ComboBox wybieram numer drogi, po czym wczytuje plik z danymi do RadioGroup w taki sposób:

KOD cpp:     UKRYJ  
     

void __fastcall TForm1::ComboBox1Select(TObject *Sender)
{
 if (ComboBox1->Text == "DK92")
        {
                String sFileName = ExtractFilePath(ParamStr(0)) + "dat\\kraj92pik.dat";

                if(!FileExists)
                {
                        Application->MessageBox(("Nie odnaleziono pliku '" + ExtractFilePath(ParamStr(0)) + "dat\\kraj92pik.dat'!").c_str(), "Uwaga! Brak pliku", MB_OK | MB_ICONSTOP);
                        RadioGroup1->Items->Clear();
                        Label1->Caption = "Nie wybrano żadnej opcji...";
                        return;
                }

                Lista->Clear();
                Lista->LoadFromFile(sFileName);

                RadioGroup1->Visible = true;
                RadioGroup1->Items->Clear();
                Label1->Caption = "Nie wybrano żadnej opcji...";

                for(int i = 0; i < Lista->Count; i++)
                {
                        RadioGroup1->Items->Add(Lista->Names[i]);
                }
}
 


5. Dzięki czemu RadioGroup wypełnia się danymi na lewo od znaku "=" z pliku z danymi.

6. Dalej dla kliknięcia w RadioGroup mam przypiętą nazwę dla Label1

KOD cpp:     UKRYJ  
void __fastcall TForm1::RadioGroup1Click(TObject *Sender)
{
        Label1->Caption = Lista->Values[Lista->Names[RadioGroup1->ItemIndex]];
}


7. I w ten sposób mam w nazwie Labela dane na prawo od znaku "=" z pliku z danymi. Oczwyiście w zależności co było kliknięte w RadioGroup.

Pytanie: A teraz zaszła potrzeba dodania gminy w postaci pliku źródłowego:

Kod: Zaznacz cały
230,818 - 232,541 km=Powiat Kutnowski, Gmina Zgierski


i wyświetlenia jej osobny na innym Labelu.

Próbowałem Twoim sposobem, ale coś mi nie tak idzie.
Avatar użytkownika
Przemyslav
Bladawiec
Bladawiec
 
Posty: 42
Dołączył(a): niedziela, 25 maja 2014, 13:59
Podziękował : 22
Otrzymał podziękowań: 0
System operacyjny: Windows 10 x64
Kompilator: C++ Builder 6
Gadu Gadu: 0
    WindowsFirefox

Re: Dzielenie tekstu...

Nowy postprzez Cyfrowy Baron » sobota, 29 października 2016, 20:01

ListBoxNames i ListBoxValues to są dwie listy typu TListBox. Po prostu umieściłem na formularzu ten komponent. To jak ty tam masz, to już twoja sprawa. Ja tylko pokazuję możliwości. W załączniku masz ten przykładowy program, którego użyłem do testów, byś lepiej zrozumiał mój kod.
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Dzielenie tekstu...

Nowy postprzez Przemyslav » sobota, 29 października 2016, 23:02

Dzięki, już rozumiem co i jak. Spróbuję pokombinować co nie co, gdyż dzielenie jak najbardziej OK, ale inaczej mam z wczytywaniem danych i klikaniem po RadioGroup.
Avatar użytkownika
Przemyslav
Bladawiec
Bladawiec
 
Posty: 42
Dołączył(a): niedziela, 25 maja 2014, 13:59
Podziękował : 22
Otrzymał podziękowań: 0
System operacyjny: Windows 10 x64
Kompilator: C++ Builder 6
Gadu Gadu: 0
    WindowsFirefox

Re: Dzielenie tekstu...

Nowy postprzez Przemyslav » sobota, 29 października 2016, 23:22

I lipa:

KOD cpp:     UKRYJ  
[C++ Error] Unit1.cpp(8451): E2316 'NameValueSeparator' is not a member of 'TStrings'
[C++ Error] Unit1.cpp(8455): E2316 'ValueFromIndex' is not a member of 'TStrings'


Czy kod jest poprawny dla C++ Builder w wersji 6.0?
Avatar użytkownika
Przemyslav
Bladawiec
Bladawiec
 
Posty: 42
Dołączył(a): niedziela, 25 maja 2014, 13:59
Podziękował : 22
Otrzymał podziękowań: 0
System operacyjny: Windows 10 x64
Kompilator: C++ Builder 6
Gadu Gadu: 0
    WindowsFirefox

Re: Dzielenie tekstu...

Nowy postprzez Cyfrowy Baron » sobota, 29 października 2016, 23:27

Wychodzi na to, że w C++Builder 6 klasa TStrings nie posiada tych metod. Pozostaje ci używanie metod LastDelimiter i SubString.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Przemyslav
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Dzielenie tekstu...

Nowy postprzez Przemyslav » sobota, 29 października 2016, 23:28

Poradziłem sobie trochę inaczej:

KOD cpp:     UKRYJ  
        String powiatgmina = Lista->Values[Lista->Names[RadioGroup1->ItemIndex]];

        Label1->Caption = (powiatgmina.SubString(1,powiatgmina.Pos(",")-1));
        Label2->Caption = (powiatgmina.SubString(powiatgmina.Pos(",")+1,powiatgmina.Length()));


Dziękuję serdecznie za pomoc :D :D
Avatar użytkownika
Przemyslav
Bladawiec
Bladawiec
 
Posty: 42
Dołączył(a): niedziela, 25 maja 2014, 13:59
Podziękował : 22
Otrzymał podziękowań: 0
System operacyjny: Windows 10 x64
Kompilator: C++ Builder 6
Gadu Gadu: 0
    WindowsFirefox

Re: Dzielenie tekstu...

Nowy postprzez Cyfrowy Baron » niedziela, 30 października 2016, 10:01

No tak, zapomniałem o Pos. Wiesz oczywiście, że Pos podaje pozycję pierwszego wystąpienia znaku, a LastDelimiter ostatniego...
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 62 gości

cron