Hello, I am trying to use cirilyc in case operator but error occured: Unit1.pas(45,11) Error: Constant and CASE types do not match (I was write an example but restruction of mail can't allow me to send it) In Delphi 7 everything is ok. When I change cirilyc to latin symbol everything is ok. Will be a fix for this problem in new versions of Lazarus or how can I can fix the problem? I am using Lazarus 0.9.29, FPC 2.3.1, SVN 21708 on Windows Vista 32bit (latest versions and updates).
Mailing lists / lazarus / 2009-09
Case error with cirilyc
20 messages · 8 people · –
- Ddmitry boyarintsev 6
- RRigel Rigel 5
- VVincent Snijders 3
- Ttheo 2
- AAlexander Klenin 1
- FFelipe Monteiro de Carvalho 1
- +2 more
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Rigel, do you mean?
var
ch : char;
begin
ch := 'Q';
case ch of
'Q': writeln('Q');
'Z': writeln('Z');
'?': writelh('?'); // cyrillic character gives the error
end;
end.If your unit is new one (created by Lazarus, rather than Delphi), then cyrillic characters are encoded as UTF8 character, that's 2 character strings.
You can achieve the same effect as Delphi, by changing file's encoding to the proper Ansi encoding:
Right Click on the editor -> File Settings -> Encoding -> select the required encoding (current Windows Ansi encoding)
(for example cp1251 for Russian charset)
Changing the encoding should fix the problem, but you might have a side effect on other (non Windows) systems.
thanks,
dmitry
dmitry boyarintsev wrote 23 lines
But this does not work if the ch is from a LCL component.
E.g
ch := Label.Caption[1];
Because the caption will be UTF8 encoded.
Vincent
Hello, I am trying to use cirilyc in case operator but error occured: Unit1.pas(45,11)…
????? Rigel wrote(I was write an example but restruction of mail can't allow me to send it)
The project (zipped) is too big, if you include an icon. Remove the icon, and compiler generated files (.exe, .o, .ppu) and you can zip and send the source.
Vincent
But this does not work if the ch is from a LCL component. E.g ch := Label.Caption[1];…
Show quoted text 5 lines
well, it would work for:
ch := UTF8Decode(Label.Caption)[1];thanks,
dmitry
dmitry boyarintsev wrote 9 lines
It should also work in FPC trunk, since "case of string" is implemented there.
The project (zipped) is too big, if you include an icon. Remove the icon, and compiler…
????? Rigel schreef: > (I was write an example but restruction of mail can't allow me to send > it)
Another idea: use a WideChar instead of Char.
DoDi
well, it would work for: ch := UTF8Decode(Label.Caption)[1]; dmitry
dmitry boyarintsev wrote 8 lines
And hope that the widechar to char conversion uses the encoding you thought it would use.
Conclusion, yes it is possible, but you must know what you are doing.
Vincent
Another idea: use a WideChar instead of Char. DoDi
Another idea: use a WideChar instead of Char.
I've tried, but it didn't work, for the same reason. Though, i've used objc branch compiler.
thanks,
dmitry
Dmitry,
I follow your instruction and now project compiles. But CASE don't effect on cirilyc symbol. In example output is without symbol. Lat symbols are ok.
Vincent, attachment without .exe, .o, .ppu is too big to and again restruction of mail can't allow me to send it.
Example with memo1, memo2, button1:
procedure TForm1.Button1Click(Sender: TObject);
var
stInp: String;
stOut: String;
i: integer;
begin
stOut := '';
stInp := Memo1.Lines.Text;
for i := 1 to length(stInp) do
Begin
// Cirilyc case
case stInp[i] of
'?': stOut := stOut + 'a'; //Cir
'?': stOut := stOut + 'b';
'?': stOut := stOut + 'v';
'?': stOut := stOut + 'g';
'?': stOut := stOut + 'd';
'a': stOut := stOut + 'a'; //Lat
'b': stOut := stOut + 'b';
'v': stOut := stOut + 'v';
'g': stOut := stOut + 'g';
'd': stOut := stOut + 'd';
End;
end;
stOut := stOut + stInp[i];
Memo2.Lines.Text := stOut;
end;Thanks,
Rigel
Show quoted text 41 lines
Dmitry,
I follow your instruction and now project compiles. But CASE don't effect on cirilyc symbol. In example output is without symbol. Lat symbols are ok.
Vincent, attachment without .exe, .o, .ppu is too big to and again restruction of mail can't allow me to send it.
Example with memo1, memo2, button1:
procedure TForm1.Button1Click(Sender: TObject);
var
stInp: String;
stOut: String;
i: integer;
begin
stOut := '';
stInp := Memo1.Lines.Text;
for i := 1 to length(stInp) do
Begin
// Cirilyc case
case stInp[i] of
'?': stOut := stOut + 'a'; //Cir
'?': stOut := stOut + 'b';
'?': stOut := stOut + 'v';
'?': stOut := stOut + 'g';
'?': stOut := stOut + 'd';
'a': stOut := stOut + 'a'; //Lat
'b': stOut := stOut + 'b';
'v': stOut := stOut + 'v';
'g': stOut := stOut + 'g';
'd': stOut := stOut + 'd';
End;
end;
stOut := stOut + stInp[i];
Memo2.Lines.Text := stOut;
end;Thanks,
Rigel
Show quoted text 9 lines
I follow your instruction and now project compiles. But CASE don't effect on cirilyc…
As Vincent mentioned earlier, LCL works with UTF8 Encoded strings.
You need to convert Memo.Text to ansi string first:
procedure TForm1.Button1Click(Sender: TObject);
var
?stInp: String;
?stOut: String;
?i: integer;
begin
?stOut := '';
?stInp := UTF8Decode(Memo1.Lines.Text); // convert the string
?for i := 1 to length(stInp) do
?Begin
....thanks,
dmitry
dmitry boyarintsev wroteYou need to convert Memo.Text to ansi string first:
Maybe you ment convert to widestring, or wanted to use the routine UTF8ToAnsi. UTF8Decode returns a widestring.
If you wanted to use UTF8ToAnsi, then the application won't work in most computers. It may work in the majority of Windows computers in Russia, just like the Delphi solution, but I recommend using a more universal solution.
Maybe you ment convert to widestring, or wanted to use the routine UTF8ToAnsi. UTF8Decode returns a widestring.
yes. UTF8ToAnsi is correct.
thanks,
dmitry
I follow your instruction and now project compiles. But CASE don't effect on cirilyc…
You might try utf8scanner http://wiki.lazarus.freepascal.org/Theodp This should do what you need:
procedure TForm1.Button1Click(Sender: TObject);
var s :TUTF8Scanner;
begin
s := TUTF8Scanner.Create(Memo1.text);
s.FindChars :='?????abvgd';
//Memo1.text:=s.GenerateCaseStatement(); //Writes the case block for you
repeat
case s.FindIndex(s.Next) of
{?} 0: s.Replace('a');
{?} 1: s.Replace('b');
{?} 2: s.Replace('v');
{?} 3: s.Replace('g');
{?} 4: s.Replace('d');
{a} 5: s.Replace('a');
{b} 6: s.Replace('b');
{v} 7: s.Replace('v');
{g} 8: s.Replace('g');
{d} 9: s.Replace('d');
end;
until s.Done;
Memo2.Text := s.UTF8String;
s.free;
end;It works with lat symbol on the right but if on the right of CASE is cyrillic symbol in Memo2.text shows '?' instead correct symbol.
procedure TForm1.Button1Click(Sender: TObject);
var
stInp: String;
stOut: String;
i: integer;
begin
stOut := '';
stInp := UTF8Decode(Memo1.Lines.Text); // convert the string
for i := 1 to length(stInp) do
case stInp[i] of
'?': stOut := stOut + '?'; //Cir --> in Memo2 shows '?'
'?': stOut := stOut + '?'; // --> in Memo2 shows '?'
'a': stOut := stOut + 'a'; //Lat --> ok
'b': stOut := stOut + 'b'; // --> ok
End;
stOut := stOut + stInp[i];
// stOut := UTF8Decode(stOut);
// Memo2.Lines.Text := UTF8Decode(stOut);
Memo2.Lines.Text := stOut;
end;Show quoted text 11 lines
I try it but don't work with cyrillic:
memo1 - ?????; output memo2 - ?????
procedure TForm1.Button1Click(Sender: TObject);
var s :TUTF8Scanner;
begin
s := TUTF8Scanner.Create(Memo1.Text);
s.FindChars :='?????';
// Memo1.text:=s.GenerateCaseStatement(); //Writes the case block for you
repeat
case s.FindIndex(s.Next) of
{?} 0: s.Replace('k');
{?} 1: s.Replace('?');
{?} 2: s.Replace('???');
{?} 3: s.Replace('g');
{?} 4: s.Replace('d');
end;
until s.Done;
Memo2.Text := s.UTF8String;
s.free;
end;Show quoted text 7 lines
...
You should not replace multiple characters with this method like
s.Replace('???');
It works for me, if I write
s.Replace('?');It outputs: k??gd then
Make sure your file encoding is UTF-8 (standard)
If you really need to replace with ??? then write the output in a second string like you did before.
It works with lat symbol on the right but if on the right of CASE is cyrillic symbol in…
--- with UTF8Scanner ----
If you're using UTF8Scanner, then you should use UTF8 encoded files. You can enable UTF8 encoding the same way, you've enabled Ansi encoding.
But, since you're in Windows, FPC compiler treats all your sources as Ansi, (even if they're UTF8Encoded).
You should add {$codepage UTF8} before 'interface' section, so the compiler knows that UTF8 is used.
--- without UTF8Scanner ----
Rigel Rigel wrote?It works with lat symbol on the right but if on the right of CASE is cyrillic symbol in Memo2.text shows '?' instead correct symbol.
You're getting '?' character, because LCL is expecting UTF8 Encoded string, while, you're filling stOut with ANSI characters. The code should be the following
procedure TForm1.Button1Click(Sender: TObject);
var
stInp: String;
stOut: String;
i: integer;
begin
stOut := '';
stInp := UTF8ToAnsi(Memo1.Lines.Text); { convert the string UTF8
string to Ansi for Case processing }
for i := 1 to length(stInp) do
case stInp[i] of // ANSI case processing
'?': stOut := stOut + '?'; //Cir --> in Memo2 shows '?'
'?': stOut := stOut + '?'; // --> in Memo2 shows '?'
'a': stOut := stOut + 'a'; //Lat --> ok
'b': stOut := stOut + 'b'; // --> ok
End;
{stOut is ANSI encoded, LCL expects UTF8Strings, so you need to encode it}
Memo2.Lines.Text := UTF8Encode(stOut);
end;There's no explicit difference between Ansi and UTF8 strings. It's up to you, to know, about strings encoding.
Keep in mind, that standard LCL component are ALWAYS using UTF8 encoded strings. For the delphi compatibility you might need to convert them to Ansi strings, but you must convert ansi strings back to UTF8 if you want assign an ANSI string to LCL component.
Also, if you're using Ansi encoded file, you need to convert string constants to the UTF8 as well, for example
Label1.Caption := UTF8Encode('???? ???');
because Label1 as standard LCL component, expects UTF8 string.The whole "mess" with UTF8/Ansi strings, is about code portability, between platforms.
thanks,
dmitry
Thank you very much, Dmitry! It works.
Best regards,
Rigel
Show quoted text 7 lines
.........
