Lazarus 2.0.10 (2020.07.11.)
Letöltés

file TStringList.Sort probléma magyar ZS betűvel

  • JohnnyK
  • JohnnyK profilkép
  • Gyakori fórumozó
  • Gyakori fórumozó
  • Hozzászólások: 78
  • Köszönetek: 16

JohnnyK válaszolt a témára: TStringList.Sort probléma magyar ZS betűvel

Lazarus 1.6.2-ben nincs szükség a jelzett kerülőmegoldásra, így a hiba úgy tűnik, hogy javítva lett, és a TStringList.Sort immár rendben rendezi sorba a magyar karaktereket is.
#2121
Megköszönték: Gábor, drschwarcz

  • JohnnyK
  • JohnnyK profilkép
  • Gyakori fórumozó
  • Gyakori fórumozó
  • Hozzászólások: 78
  • Köszönetek: 16

JohnnyK válaszolt a témára: TStringList.Sort probléma magyar ZS betűvel

Meglett a sorbarendezési probléma oka, kibogarásztam a forrásokból. Megosztanám, hátha valaki más is beleütközik majd a jövőben ebbe a dologba...
Röviden: Az említett UTF8Osszehasonlitas függvénybe egy WideCompareStr függvényt kell beilleszteni, és működni fog a sorbarendezés mind Windows-on, mind Linuxon.
function UTF8Osszehasonlitas(List: TStringList;Index1: Integer;Index2: Integer):Integer;
begin
  Result := WideCompareStr(WideString(List[Index1]),WideString(List[Index2]));
end;
// Stringlist sorbarendezése:
SL.CustomSort(@UTF8Osszehasonlitas);

Bővebben: A LazUTF8-beli UTF8CompareStrCollated függvény Linux esetében ezt a WideCompareStr függvényt hívja meg alapból, Windows esetében viszont egy AnsiCompareStr(UTF8ToSys(S1), UTF8ToSys(S2)) nevű függvényt. Az UTF8ToSys függvény a régebbi Lazarus és Freepascal alatt átkonvertálták a string-eket Ansi-vé, az új viszont meghagyja őket UTF8-nak. Maga az AnsiCompareStr végső soron meghívott egy Win32 specifikus CompareStringA függvényt, és az sorba is rendezi az Ansi kódolású stringeket. Viszont most UTF8-akat kapott, emiatt rossz eredményeket adott vissza. A WideCompareStr viszont összességében egy CompareStringW nevű Win32 specifikus függvényt hív meg, ami meg UTF8 stringeket vár, és emiatt jól rendez sorba. A LazUTF8.pas unit tartalmának változtatása nélkül nem találtam más, működő megoldást a problémára.
#1883
Megköszönték: Gábor

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 432
  • Karma: 8
  • Köszönetek: 70

Gábor válaszolt a témára: TStringList.Sort probléma magyar ZS betűvel

Nézelődtem egy kicsit, és...

A Free Pascal új változatának használata a felhasználók munkájára is hatással lehet. A karakterkezeléssel kapcsolatban például ezek:
Amint az a Lazarus 1.6 megjelenésének bejelentés ében is olvasható, a Lazarus 1.6 az Free Pascal 3.0-ra épül ellentétben a 1.4.* sorozattal, melyben még a 2.6.4 volt a főszereplő.
#1876

  • JohnnyK
  • JohnnyK profilkép
  • Gyakori fórumozó
  • Gyakori fórumozó
  • Hozzászólások: 78
  • Köszönetek: 16

JohnnyK válaszolt a témára: TStringList.Sort probléma magyar ZS betűvel

Szia!
Köszi a választ. Kipróbáltam a kódot, és összevetettem, hogy miket kaptam eredményként az egyes operációs rendszerek, nyelvek és lazarus verziók alatt mind a Sort, mint a CustomSort használatával. Az látható, hogy:
  • a Libreoffice konzekvensen rendez sorba az Excellel
  • Linux alatt a verzióváltás nem okozott különbséget, a Sort és a Customsort is azonos, különbségek csak a rendszer nyelvének módosításakor jönnek elő, ám ezek is konzekvensek a Libreoffice-al és az Excellel
  • Windows alatt csak a nyelvmódosítás nem okozott majdnem különbséget (ezért talán nem is biztos, hogy jól sikerült átállítanom azt), minden más viszont igen. A legjobban a magyar, 1.4-es verziójú CustomSort függvény hasonlított a várt eredményhez
A unit-ok forrásában megpróbálok majd szétnézni, hátha kiderül, hogy mi a turpisság az egészben. Az eredménytáblázatom:
ABCDEFGHIJKLMNOPQRS
LinuxLinuxLinuxLinuxLinuxLinuxLinuxLinuxWinWinWinWinWinWinWinWinWinLin-WinLin-Win
1.2.61.2.61.2.61.2.6v1.6v1.6v1.6v1.6v1.4v1.4v1.4v1.4v1.6v1.6v1.6v1.6ExcelLibreLibre
ENENHUHUENENHUHUENENHUHUENENHUHU20104.2.8.24.2.8.2
SortCsortSortCsortSortCsortSortCsortSortCsortSortCsortSortCsortSortCsortHUENHU
aaaaaaaaaűaaaaaaaaa
ááááááááíőíáasasasasááá
asasasasasasasasáaáasassassassassasasas
ásásásásásásásásásáásásasyasyasyasyásásás
assassassassassassassassássasássassaszaszaszaszassassass
ássássássássássássássássásyásásyássazazazazássássáss
asyasyasyasyasyasyasyasyászassászasyazsazsazsazsasyasyasy
ásyásyásyásyásyásyásyásyázássázásyazyazyazyazyásyásyásy
aszaszaszaszaszaszaszaszázyasyázyaszazzazzazzazzaszaszasz
ászászászászászászászászázzásyázzászbbbbászászász
azazazazazazazazázsaszázsazccccazazaz
ázázázázázázázázéászéázddddázázáz
azsazsazyazyazsazsazyazyöazöazyeeeeazyazsazy
ázsázsázyázyázsázsázyázyüázüázyffffázyázsázy
azyazyazzazzazyazyazzazzóazyóazzggggazzazyazz
ázyázyázzázzázyázyázzázzasázyasázzhhhházzázyázz
azzazzazsazsazzazzazsazsúazzúazsiiiiazsazzazs
ázzázzázsázsázzázzázsázsassázzassázsjjjjázsázzázs
bbbbbbbbasyazsasybkkkkbbb
ccccccccaszázsaszcllllccc
ddddddddazbazdmmmmddd
eeeeeeeeazycazyennnneee
ééééééééazzdazzéooooééé
ffffffffazseazsfppppfff
ggggggggbébgqqqqggg
hhhhhhhhcfchrrrrhhh
iiiiiiiidgdissssiii
ííííííííeheíssssssssííí
jjjjjjjjfifjsysysysyjjj
kkkkkkkkgígkszszszszkkk
llllllllhjhlttttlll
mmmmmmmmikimuuuummm
nnnnnnnnjljnvvvvnnn
ooooooookmkowwwwooo
óóóóóóóólnlóxxxxóóó
ööööööööőoőöyyyyööö
őőőőőőőőűóűőzzzzőőő
ppppppppmömpzszszszsppp
qqqqqqqqnpnqzyzyzyzyqqq
rrrrrrrroqorzzzzzzzzrrr
ssssssssprpsáááásss
ssssssssssssssssqsqssásásásásssssss
sysysysysysysysyrssrsyássássássásssysysy
szszszszszszszszssysszásyásyásyásyszszsz
ttttttttssszsstászászászászttt
uuuuuuuusytsyuázázázázuuu
úúúúúúúúszuszúázsázsázsázsúúú
üüüüüüüütútüázyázyázyázyüüü
űűűűűűűűuüuűázzázzázzázzűűű
vvvvvvvvvvvvéééévvv
wwwwwwwwwwwwííííwww
xxxxxxxxxxxxóóóóxxx
yyyyyyyyyyyyööööyyy
zzzzzzzzzzzzúúúúzzz
zszszyzyzszszyzyzyzyzyzyüüüüzyzszy
zyzyzzzzzyzyzzzzzzzzzzzzőőőőzzzyzz
zzzzzszszzzzzszszszszszsűűűűzszzzs
#1870

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 432
  • Karma: 8
  • Köszönetek: 70

Gábor válaszolt a témára: TStringList.Sort probléma magyar ZS betűvel

Nálam az alábbi kód a zy-t előrébb sorolja be mint a zs-t, habár a hosszú ékezetes magánhangzók a rövid párjaikkal "majdnem" egyenértékűként vannak kezelve (Linux, LANG=hu_HU.UTF-8).
Ezt a kódot (bár zs és zy nélkül) már írtam a Rendezes magyar abc szerint című témában...
var
  SL:TStringList;
  I:Integer;
 
{
 // A WideStrinManager is valószínűleg ugyanezt csinálja, az eredmény legalábbis ugyanaz. Lásd az SL.Sort(..) és az SL.CustomSort(...) hívásokat lentebb (utóbbit  megjegyzésben)...
function UTF8Osszehasonlitas(List: TStringList;Index1: Integer;Index2: Integer):Integer;
begin
   Result:=UTF8CompareStrCollated(List[Index1],List[Index2]);
end;
}
 
begin
  SL:=TStringList.Create;
  SL.Add('a');
  SL.Add('á');
  SL.Add('e');
  SL.Add('é');
  SL.Add('i');
  SL.Add('í');
  SL.Add('o');
  SL.Add('ó');
  SL.Add('ö');
  SL.Add('ő');
  SL.Add('u');
  SL.Add('ú');
  SL.Add('ü');
  SL.Add('ű');
 
  SL.Add('zz');
  SL.Add('ss');
  SL.Add('zs');
  SL.Add('sz');
  SL.Add('sy');
  SL.Add('zy');
 
  SL.Add('áz');
  SL.Add('ázz');
  SL.Add('áss');
  SL.Add('ázs');
  SL.Add('ász');
  SL.Add('ás');
  SL.Add('ásy');
  SL.Add('ázy');
 
  SL.Add('az');
  SL.Add('azz');
  SL.Add('ass');
  SL.Add('azs');
  SL.Add('asz');
  SL.Add('as');
  SL.Add('asy');
  SL.Add('azy');
 
  // a fentebbi magánhangzókat és "szavakat" az alábbi mássalhangzók közé helyesen kell besorolnia a .Sort eljárásnak
 
  SL.Add('b');
  SL.Add('c');
  SL.Add('d');
  SL.Add('f');
  SL.Add('g');
  SL.Add('h');
  SL.Add('j');
  SL.Add('k');
  SL.Add('l');
  SL.Add('m');
  SL.Add('n');
  SL.Add('p');
  SL.Add('q');
  SL.Add('r');
  SL.Add('s');
  SL.Add('t');
  SL.Add('v');
  SL.Add('w');
  SL.Add('x');
  SL.Add('y');
  SL.Add('z');
 
  SL.Sort;
  // SL.CustomSort(@UTF8Osszehasonlitas); // Lásd az UTF8Osszehasonlitas eljárást megjegyzésben fentebb...
 
  for I:=0 to SL.Count-1 do WriteLn(SL[I]);
 
  SL.Free;
 
end.
... és a kapott eredmény:
a
á
as
ás
ass
áss
asy
ásy
asz
ász
az
áz
azy
ázy
azz
ázz
azs
ázs
b
c
d
e
é
f
g
h
i
í
j
k
l
m
n
o
ó
ö
ő
p
q
r
s
ss
sy
sz
t
u
ú
ü
ű
v
w
x
y
z
zy
zz
zs
Ha windows-on nem így működik akkor javaslom a TStringList.CustomSort használatát, melynek egy általad kidolgozott összehasonlító függvényt kell átadni paraméterként...

Egyébként én nem látok ilyen működési eltérésre okot adó "új módszer"-t a Free Pascal és a Lazarus e területet érintő unit-jaiban (és a változások listájában sem), persze lehet, hogy csak én nem vagyok elég figyelmes...
Te találtál valami ilyet a unit-ok forráskódjában?
#1869

  • JohnnyK
  • JohnnyK profilkép
  • Gyakori fórumozó
  • Gyakori fórumozó
  • Hozzászólások: 78
  • Köszönetek: 16

JohnnyK létrehozta a témát: TStringList.Sort probléma magyar ZS betűvel

Sziasztok!
Frissítettem az 1.6-os Lazarusra, és a TStringList.Sort eljárás immáron máshogy rendez sorba, mint előtte. Igen, tudom, hogy az új Freepascal jelentős string változásokat eredményez, mégis kutakodnék, hogy milyen lehetőségek vannak kezelni az új helyezet.
A példa: magyar nyelvű windowsban egy Excelben a ZY és a ZS sorbarendezésekor a ZY előrébb van, mint a ZS. A régi Lazarus (és Freepascal) is így rendezte sorba ezeket az szövegeket. Az új változatban viszont a ZS előrébb kerül a ZY-hoz képest. LibreOffice-ban van lehetőség szortírozási nyelvet és karakterkészletet beállítani, így angol esetben ZS, majd ZY a sorrend, magyar esetben ZY, ZS a sorrend. Azt, hogy az iskolában hogyan kell őket nyelvtanilag helyesen sorbarendezni, azt most hagyjuk :)
A kérdésem: mit tudok állítani a .Sort metóduson, hogy a régi szerint rendezzen sorba, vagy mit tudok állítani az Office beállításaiban, hogy egy Excel is eszerint az új módszer szerint szortírozzon?
#1866