Author Topic: WideString to AnsiString conversion  (Read 43107 times)

plashenkov

  • New Member
  • *
  • Posts: 24
WideString to AnsiString conversion
« on: June 19, 2013, 09:57:49 pm »
Hello!

I found such issue.
For example, I would like to convert WideString to AnsiString:

Code: [Select]
WStr := 'Peter Müller';
AStr := AnsiString(WStr);

In Delphi I get: AStr = 'Peter Muller',
but in Lazarus I get: AStr = 'Peter M?ller'.
(I have Russian Windows, and Russian symbols both Delphi and Lazarus convert correctly, but such symbols like ü, etc. --- they convert differently).

Is it possible in Lazarus to make the conversion as it is presented in Delphi?
That's extremely critical thing for me due to one my app is written in Delphi (and it is too complex to rewrite it under Lazarus now), and the second one is already in Lazarus. And it's important they give exactly the same result.

Maybe some WinAPI function exists which converts Wide to Ansi like Delphi does.
Thank you!

Sincerely,
Yury
« Last Edit: June 19, 2013, 10:00:29 pm by plashenkov »

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1947
Re: WideString to AnsiString conversion
« Reply #1 on: June 19, 2013, 11:04:04 pm »
Lazarus uses UTF-8.

You could try

AStr := UTF8Decode(WStr);

plashenkov

  • New Member
  • *
  • Posts: 24
Re: WideString to AnsiString conversion
« Reply #2 on: June 20, 2013, 07:03:49 am »
Actually in Lazarus I use:

AStr := Utf8ToAnsi(UTF8Str);

But it gives the same result: it replaces some symbols with question signs.

UTF8Decode converts UTF8 string to UnicodeString. This is not what I need. I need WideString (or UTF8 string in Lazarus) to AnsiString conversion.

poiuyt555

  • Jr. Member
  • **
  • Posts: 91
Re: WideString to AnsiString conversion
« Reply #3 on: June 20, 2013, 09:59:48 am »
Utf8toSys or utf8toansi works correct for transform: UTF8->ANSI (for my 1251 rus codepage works ok)
Symbol ü is not presented in rus codepage 1251, that is why you get ? - this is the correct work.

But how to convert ü to english u (or russian и) - this is the another question, and i don't know.
« Last Edit: June 20, 2013, 10:19:57 am by poiuyt555 »

plashenkov

  • New Member
  • *
  • Posts: 24
Re: WideString to AnsiString conversion
« Reply #4 on: June 20, 2013, 10:41:33 am »
Yes, surely this is not Lazarus error or mistake.
But Delphi does it in the other way. It converts ü to u although it is not presented in Russian codepage.
Maybe there is some method in Lazarus to do the same?

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1947
Re: WideString to AnsiString conversion
« Reply #5 on: June 20, 2013, 10:48:29 am »
I don't really understand your problem.
Maybe you want to convert from one encoding to UTF-8?

http://lazarus-ccr.sourceforge.net/docs/lcl/lconvencoding/index-5.html

plashenkov

  • New Member
  • *
  • Posts: 24
Re: WideString to AnsiString conversion
« Reply #6 on: June 20, 2013, 11:07:56 am »
theo, look.

One application is written in Delphi.
The second one --- license generator for the first app --- written in Lazarus.

In the license checking algorithm of the first app the following conversion is used: AStr := AnsiString(UserName);
UserName is WideString, AStr is AnsiString, and it (AStr) is used in the complex algorithm of license key generation.

The second app is the separate key generator. And it gives the wrong result due to only this nuance.
Delphi WideString to AnsiString is different from Lazarus Utf8ToAnsi(). This is why the second app (key generator) gives totally wrong keys which are not compatible with the first app.

The only way is to fix the problem is to use the same WideString to AnsiString conversion like Delphi has. Maybe there is some way to do that?

poiuyt555

  • Jr. Member
  • **
  • Posts: 91
Re: WideString to AnsiString conversion
« Reply #7 on: June 20, 2013, 11:22:29 am »
Maybe, manualy replace in string from ü to english u and then decode it to ansi?
But i'am not suhe it would work...
I think, yes, maybe some WinAPI may help.

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1947
Re: WideString to AnsiString conversion
« Reply #8 on: June 20, 2013, 11:37:44 am »
It does work imho. Please test this:

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var ws:WideString;
  utf8s:AnsiString;
  s:AnsiString;
  i:integer;
begin
  utf8s:='Mü';
  for i:=1 to length(utf8s) do Memo1.lines.add(Inttostr(ord(utf8s[i])));
  ws:=UTF8Decode(utf8s);
  s:=ws;
  Memo1.Lines.Add(' ');
  for i:=1 to length(s) do Memo1.lines.add(Inttostr(ord(s[i])));
end;

I get for UTF-8:
77
195
188
 
For ANSI:
77
252

If you have a different System encoding, you probably need a conversion from here
http://lazarus-ccr.sourceforge.net/docs/lcl/lconvencoding/index-5.html
« Last Edit: June 20, 2013, 11:40:53 am by theo »

plashenkov

  • New Member
  • *
  • Posts: 24
Re: WideString to AnsiString conversion
« Reply #9 on: June 20, 2013, 11:41:16 am »
It gives me the following output:

77
195
188
 
77
63

63 is the "?"sign. ((

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1947
Re: WideString to AnsiString conversion
« Reply #10 on: June 20, 2013, 11:46:57 am »
Yes, then you have to convert "manually".

Try this:

Code: [Select]
uses LConvEncoding;
....

procedure TForm1.Button1Click(Sender: TObject);
var ws:WideString;
  utf8s:AnsiString;
  s:AnsiString;
  i:integer;
begin
  utf8s:='Mü';
  for i:=1 to length(utf8s) do Memo1.lines.add(Inttostr(ord(utf8s[i])));
  ws:=UTF8Decode(utf8s);
  s:=UTF8ToISO_8859_1(UTF8Encode(ws));
  Memo1.Lines.Add(' ');
  for i:=1 to length(s) do Memo1.lines.add(Inttostr(ord(s[i])));
end;

plashenkov

  • New Member
  • *
  • Posts: 24
Re: WideString to AnsiString conversion
« Reply #11 on: June 20, 2013, 11:53:22 am »
Now it converts ü -> u correctly, but does not convert cyrillic.
For example, "Привет" gives totally empty result.

But Delphi converts both cyrillic and "ü" (and similar) correctly. Interesting, what algorithm does Delphi use?

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1947
Re: WideString to AnsiString conversion
« Reply #12 on: June 20, 2013, 11:58:11 am »
Not sure.
You can not tell what character e.g. ANSI "252" means unless you know the encoding.
Can't you convert the whole thing to Unicode?
This would be the best solution imho.

plashenkov

  • New Member
  • *
  • Posts: 24
Re: WideString to AnsiString conversion
« Reply #13 on: June 20, 2013, 12:14:37 pm »
I would like to forget Ansi and different encodings as a nightmare, and to use only Unicode, but unfortunately I cannot change the Delphi app.

Quote
Not sure.
It's really so. String which contains cyrillic as well as other signs like ü correctly transforms to readable Ansi string which contains Ansi cyrillic letters as well as "u", not "?" sign.

plashenkov

  • New Member
  • *
  • Posts: 24
Re: WideString to AnsiString conversion
« Reply #14 on: June 20, 2013, 12:17:15 pm »
Well, I hope I will solve this somehow.
Thank you theo, poiuyt555 for your help!

 

TinyPortal © 2005-2018