Strona 1 z 2

Obsługa wielu języków - TStringList?

Nowy postNapisane: poniedziałek, 28 lipca 2008, 13:30
przez Koziol
Ostatnio przeszukuje sobie sieć w poszukiwaniu implementacji obsługi wielu języków w BCB ale niestety nic konkretnego znaleźć mi się nie udało ;( jedyną rzeczą jaką udało mi się dowiedzieć jest że można się posłużyć komponentem/klasą TStringList ale niestety jak widzę można się tam odwoływać tylko przez numer indexu znaczy:
Kod: Zaznacz cały
TStringList *Lista = new TStringList;
Lista->Add("asd");
cos = Lista->Strings[0];

I pytanie czy nie da się tu nadać indexów słownych jak np. w PHP? tam rzecz jest bardzo prosta:
Kod: Zaznacz cały
$lista=array();
$lista['jakas_nazwa'] = "asd";

Czy w BCB da rade osiągnąć coś takiego np przy użyciu ów klasy?

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: poniedziałek, 28 lipca 2008, 13:48
przez Cyfrowy Baron
Nie wiem czy o to pytasz, ale w C++ builder działa tylko język C++, można wstawiać wstawki assamblerowe w specjalnych blokach, można dodawać pliki zawierające kod w Delphi, Pascalu, ale nie słyszałem np. by można było dodawać kod w Visual Basic, ale na pewno nie można wstawiać języków skryptowych czyli HTML, Java, czy PHP.




Klasa TStrings jest klasą wirtualną i nie może występować samodzielnie, ale może być składnikiem innych klas jak. np. TStringList, TLisBox, TListView, TComboBox, itp. NIe jest niczym więcej jak tablicą przechowującą znaki i łańcuchy znaków typu AnsiString.

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: poniedziałek, 28 lipca 2008, 13:50
przez Koziol
A ja nie chce wstawki z PHP ja chciał bym uzyskać efekt jak w PHP czyli zamiast indexów liczbowych indexy słowne.
Cyz coś takiego da się uzyskać.

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: poniedziałek, 28 lipca 2008, 13:56
przez Cyfrowy Baron
Wyrażasz się nieprecyzyjnie.
Tablice w C++ zawsze mają numery indeksów, ale są to numery.

Przykład tworzenia takiej tablicy:

Kod: Zaznacz cały
AnsiString tablica[] = {"tekst 1", "tekst 2", "tekst 3"};

Label1->Caption = tablica[2];// na Label1 pokaże się tekst tekst 2


Tablica TStringList może zawierać wartości i nazwy przypisane do wartości, czyli w zasadzie nazwa jest tutaj nazwą indeksu, który posiada jakąś wartość.
Opisałem to ► patrz serwis: Cyfrowy Baron w dziale: Porady | TStringList | Tworzenie listy zawierającej nazwy i wartości przypisane do nazw.

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 09:56
przez wargo
Ale jemu chodzi o to że zamiast numerów chce podać słowo, na pewno inaczej to będzie działać, to jest tak samo jak tablice php. I nie chodzi lub nie musi chodzić o wybranie z tablicy.
Tutaj pokażę o co chodzi:
Kod: Zaznacz cały
//php:
//Przykład 1
$x = array("asd" => "asasasasas");
echo 
$x["asd"];//wyświetli asasasasss
//2
$userdata["username"] = "wargo";
echo 
$userdata["username"]; //wyświetli: wargo
 

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 13:29
przez Cyfrowy Baron
Czegoś takiego nie ma w C++. Indeksy w tablicach są numerami, można co prawda definiować nazwy i przypisywać im tylko numery, wtedy można by się odwoływać do nazw, ale nazwy muszą być zdefiniowane:

Kod: Zaznacz cały
void __fastcall TForm1::Button2Click(TObject *Sender)
{
const int nazwa_1 = 0;
const int nazwa_2 = 1;
const int nazwa_3 = 2;
const int nazwa_4 = 3;
// itd...
AnsiString Tablica[] = {"tekst a", "tekst b", "tekst c", "tekst d"};

Label1->Caption = Tablica[nazwa_3]; // zostanie wyświetlony napis: tekst c
}


tłumaczysz to tak zawile, że na dobrą sprawę nie wiem o co Tobie właściwie chodzi. Nie rozumiem jak indeks tablicy może być nazwą. Tablica to zbiór wartości uszeregowanych w kolejności, to ta kolejność decyduje o numerach indeksów. Skąd w tablicy zamiast numerów miały by się wziąć nazwy, przecież trzeba by najpierw stworzyć te nazwy, a potem przyporządkować je poszczególnym elementom tablicy.

Tak działa tablica TStringList ( ► patrz serwis: Cyfrowy Baron dzial: Porady | TStringList | Tworzenie listy zawierającej nazwy i wartości przypisane do nazw) ponieważ pozwala definiować nazwy, ale trzeba też od razu przypisywać tym nazwom wartości. Ta tablica tak naprawdę nie różni się niczym od innych tablic, ale klasa TStringList ma wbudowany mechanizm rozdzielający wartości poszczególnych indeksów na nazwy i wartości, a wykorzystuje do tego celu separator '='.
Prosty przykład działania takiej tablicy:

Kod: Zaznacz cały
void __fastcall TForm1::Button2Click(TObject *Sender)
{
TStringList *tablica = new TStringList;
tablica->Add("Opel=Kadet");
tablica->Add("Ford=Escort");
tablica->Add("Polonez=Caro");
tablica->Add("Fiat=Uno");

Label1->Caption = tablica->Values["Polonez"]; // wyświetlony zostanie napis: Caro

delete tablica;
}

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 14:12
przez Darek_C++
Jak dla mnie to tytuł tego topicku jest całkowicie nietrafny do jego kontekstu i kojarzy mi się z unicode i rozszerzonymi zakresami znaków np chińskim etc., etc. :)

Jeśli zaś chodzi o funkcjonalność typu tablicy asocjacyjnej z PHP w C++ implementuje to kontener typu map z STL
Nie wnikając w zagadnienie iteratorów przykład dodawanie i pobieranie danych:
Kod: Zaznacz cały
#include <map> // nalezy dolączyc
using namespace std;
map<String,String> myMap; // tworzymy zmienna typu map;
void __fastcall TForm1::Button2Click(TObject *Sender)
{


    myMap.insert(pair<String, String>("klucz1","Wartość 1"));
    myMap.insert(pair<String, String>("klucz2","Wartość 2"));
    myMap.insert(pair<String, String>("klucz3","Wartość 3"));

    Memo1->Lines->Add( myMap["klucz2"]);
    Memo1->Lines->Add( myMap["klucz1"]);
    Memo1->Lines->Add( myMap["klucz3"]);

    Memo1->Lines->Add("---------------");

    map<String, String> myMap2;

    myMap["klucz1"] = "Wartość 1";
    myMap["klucz2"] = "Wartość 2";
    myMap["klucz3"] = "Wartość 3";

    Memo1->Lines->Add( myMap["klucz2"]);
    Memo1->Lines->Add( myMap["klucz1"]);
    Memo1->Lines->Add( myMap["klucz3"]);
}

Czyli zupełnie jak w PHP i array();

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 14:25
przez Cyfrowy Baron
A jak się temu co napisałeś dokładniej przyjrzysz to się okaże, że TStringList oferuje to samo, w zasadzie opisany przeze mnie mechanizm TStrinList opiera się na tym co podałeś.

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 14:44
przez Darek_C++
Z tym, że kontener map możemy bardzo wydajne przeszukiwać.

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 14:46
przez Koziol
z tą róznicą że przy użyciu TStringList możemy również prawie automatycznie przypisywać zmienne do napisów na button'ach itp.

// przejrzałem dokładnie na stronce opis do TStringList

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 14:51
przez Darek_C++
A z map nie ?
Kod: Zaznacz cały
Button1->Caption = myMap["klucz2"];

Zastanów się zamim coś napiszesz :lol:

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 16:01
przez Koziol
lol... albo ty sie naucz czytać ze zrozumieniem "prawie automatycznie"

Kod: Zaznacz cały
// Plik źródłowy np. Unit1.cpp
//--------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
Lista = new THashedStringList;
Lista->Add("Button1=Zapisz");
Lista->Add("Button2=Otwórz");
Lista->Add("Button3=Zamknij");
Lista->Add("Button4=OK");
Lista->Add("zamieszkały miasto=Płońsk");
Lista->Add("adres=top secret");
Lista->Add("telefon kom.:=506 115 671");
}
//--------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
for(int i = 1; i <= 4; i++)
{
  String name = "Button" + IntToStr(i);
  dynamic_cast<TButton *>(FindComponent(name))->Caption = Lista->Values[name];
}
}
//--------------------------------


przy odpowiedniejk zmianie tego kodu bedziesz mogl pobrac index'y, a przy takiej tablicy ja ty proponujesz nie wiem czy to sie uda, bo chyba w BCB nie ma petli foreach

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 16:10
przez Darek_C++
Twój przykład:
Kod: Zaznacz cały
void __fastcall TForm1::Button5Click(TObject *Sender)
{

    myMap["Button1"] = "Zapisz";
    myMap["Button2"] = "Otwórz";
    myMap["Button3"] = "Zamknij";
    myMap["Button4"] = "OK";
    for(int i = 1; i <= 4; i++)
    {
        String name = "Button" + IntToStr(i);
        dynamic_cast<TButton *>(FindComponent(name))->Caption = myMap["Button"+(String)i+""];
    }
}


BCB nie ogranicza użytkownika do komponentów wizualnych i tych nie wizualnych jak przedmiotowa kalsa TStringList z VCL, ale jak najbardziej obsługuje cały język C++. Druga sprawa to jest wydajność...

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 17:51
przez Cyfrowy Baron
Te dysputy do niczego nie prowadzą. Klasa TStringList wykorzystuje mechanizm kontener map, więc jest równie wydajna, ten sam mechanizm wyszukiwania. Mogą być pewne opóźnienia przy przetwarzaniu łańcucha znaków, gdyż zapis: nazwa=wartość wymaga rozbicia na dwa wyrazy i wrzucenia do tablicy. Niemniej jednak klasa TStringList oferuje prostszy w obsłudze i bardziej zautomatyzowany sposób pobierania i przechowywania danych. Kolejna zaleta to możliwość łatwego zapisania zawartości TStringList do pliku, podczas gdy w przypadku mapowania, konieczne jest stworzenie struktury która będzie pośredniczyć w zapisie i odczycie danych. Klasa TStringList hermetyzuje zmienne i funkcje, w efekcie jej użycie ogranicza się do wywołania kilku funkcji.

To którego sposobu użyjemy zależy od potrzeb, poza tym STL oferuje znacznie większą funkcjonalność, przedstawiona w przykładzie to tylko jedna z możliwości.
Wydaje mi się, że na potrzeby prostej tablicy lepiej skorzystać z klasy TStringList, gdyż posiada ona już wydajny mechanizm, podczas gdy funkcjonalne korzystanie z STL wymaga stworzenia funkcji z mechanizmem obsługującym tablice.

Re: Obsługa wielu języków - TStringList?

Nowy postNapisane: wtorek, 29 lipca 2008, 19:09
przez Darek_C++
W tym topicku mowa o tablicach asocjacyjnych z PHP wiec komtentt typu map jest ich odpowiednikiem.
W kwestii "bo chyba w BCB nie ma petli foreach" proszę bardzo za pomocą przychodzą iteratory:
Kod: Zaznacz cały
map<String,String>::iterator it;

myMap["klucz1"] = "Wartość 1";
myMap["klucz2"] = "Wartość 2";
myMap["klucz3"] = "Wartość 3";

for ( it=myMap.begin() ; it != myMap.end(); it++)
{
   Memo1->Lines->Add(myMap[(*it).first]);
   Memo1->Lines->Add((*it).second);
}

I mamy odpowiednik foreach z PHP.
Nie wiem czy taką funkcjonalność posiada TStringList bez rozbicia na części po znaku = Twojego przykładu CB implementacji tablicy asocjacyjnej. Poza tym ja wcale nie umniejszam zalet TStringList, ale podaje inne rozwiązanie z STL.