Funkacja kompiluje się w Delphi a w Lazarusie już nie.

0
function PL (lancuch : string) : string;
var tmp  : string;
i : integer;
begin
for i := 1 to lancuch.Length do
   case lancuch[i] of
   '¹' : tmp:=tmp + 'ą';
   'æ' : tmp:=tmp + 'ć';
   'ê' : tmp:=tmp + 'ę';
   '³' : tmp:=tmp + 'ł';
   'ñ' : tmp:=tmp + 'ń';
   'ó' : tmp:=tmp + 'ó';
   'œ' : tmp:=tmp + 'ś';
   '¿' : tmp:=tmp + 'ż';
   'Ÿ' : tmp:=tmp + 'ź';
   '¥' : tmp:=tmp + 'Ą';
   'Æ' : tmp:=tmp + 'Ć';
   'Ê' : tmp:=tmp + 'Ę';
   '£' : tmp:=tmp + 'Ł';
   'Ñ' : tmp:=tmp + 'Ń';
   'Ó' : tmp:=tmp + 'Ó';
   'Œ' : tmp:=tmp + 'Ś';
   '¯' : tmp:=tmp + 'Ż';
   '' : tmp:=tmp + 'Ź';
   else tmp:=tmp+lancuch[i];
   end;
Result := tmp;
end;

W Lazarusie mam komunikat "constant and case types do not match". W Delphi jest okej.

0

'' : tmp:=tmp + 'Ź'; - pusty znak?
poza tym zawsze zadziała:

case Ord(lancuch[i]) of
	Ord('¹') : ..
0

Kompilacja zatrzymuje się na

ord('¹') : tmp:=tmp + 'ą';

Ordinal expression expected.
Natomiast

ord('a') : tmp:=tmp + 'ą';

działa. Nie rozumiem tego. Może edytor nie rozpoznaje tych znaczków jako litery?

0

Te znaczki działają pod Delphi jak przestawisz formę na kodowanie UTF8. Nie wiem jak to się robi w Lazarusie ale zapewne także trzeba przełączyć się na kodowanie UTF8.
Poza tym zamiast wpisywać takie krzaczki w których łatwo się pomylić lepiej użyć funkcji Chr(kod_ASCII), czyli:
zamiast:

case lancuch[i] of
   '¹' : tmp:=tmp + 'ą';

napisz:

case lancuch[i] of
   Chr(185) : tmp:=tmp + 'ą';
0

Dziękuję za podpowiedź. Działa.

3
didzni napisał(a):

W Lazarusie mam komunikat "constant and case types do not match". W Delphi jest okej.

Błąd ten jasno informuje o źródle problemu – typy danych się różnią, co nie jest dopuszczalne. Wszystko dlatego, że lancuch[i] zwraca jednobajtowy znak, a literał np. 'æ' to dwubajtowy ciąg znaków – stąd błąd kompilacji.

Nie wiem po jaką cholerę sam piszesz taką funkcję, skoro są już gotowe, np. AnsiToUtf8 z modułu LazUTF8.… :/

robertz68 napisał(a):

Nie wiem jak to się robi w Lazarusie ale zapewne także trzeba przełączyć się na kodowanie UTF8.

UTF-8 jest natywnym kodowaniem – nie trzeba niczego przełączać. Chyba że na ANSI, to wtedy najpewniej zatrybi bez żadnych zmian w kodzie, ale i tak odradzam takich praktyk.

0

OK, ale dlaczego w Delphi ta funkcja działa bez żadnych dodatkowych zabiegów? Może szablon string jest inaczej napisany? Mogę normalnie porównać literał z pojedynczym znakiem wyjętym ze stringa indeksem.

0
didzni napisał(a):

OK, ale dlaczego w Delphi ta funkcja działa bez żadnych dodatkowych zabiegów?

Bo Delphi, którego używasz, obsługuje kod źródłowy w postaci jednobajtowego ANSI, dlatego każdy z literałów wewnątrz instrukcji wyboru jest zwykłym znakiem (a nie łańcuchem) i możesz go porównać do innego znaku. Albo obsługuje unikod, a podane w instrukcji wyboru literały traktowane są jako unikodowe znaki.

Skąd mam wiedzieć – nie napisałeś o które Delphi chodzi…

0

10.3.3

0

@didzni: sprawdź poniższy kod i daj znać co wyskoczy w konsoli:

WriteLn(Length(Char('æ')));
WriteLn(Length(String('dæb')));

W Lazarusie (bez rzutowania) jest to 2 i 4, czyli prawidłowo – zgodnie z UTF-8.

Jeśli dobrze rozumiem dokumentację to ta wersja Delphi domyślnie wykorzystuje typ UnicodeString w postaci UTF-16, więc powinieneś w konsoli zobaczyć 1 i 3.

0
WriteLn(Length(Char('æ'))); 

W Lazarusie z rzutowaniem jest błąd kompilacji. Illegal type conversion: "Constant String" to "Char". Nie chce przekonwertować 'æ' do char. Bez rzutowania jest 2 i 4. W Delphi, o ile dobrze myślę, 'æ' to jeden bajt, więc rzutowanie się udaje.

1
didzni napisał(a):

W Lazarusie z rzutowaniem jest błąd kompilacji. Illegal type conversion: "Constant String" to "Char".

Prawidłowo – nie da się zrzutować całego ciągu znaków na jeden znak.

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