Lazarus

Free Pascal => Beginners => Topic started by: YiannisKam on April 01, 2023, 12:47:58 pm

Title: How to save greek letters to a variable?
Post by: YiannisKam on April 01, 2023, 12:47:58 pm
Code: Pascal  [Select][+][-]
  1. program Hello;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   windows, sysutils;
  7.  
  8. var
  9.   name: utf8String;
  10.  
  11. begin
  12.   SetConsoleOutputCP(CP_UTF8);
  13.  
  14.   writeln('Πως σε λένε φίλε μου;');
  15.   readln(name);
  16.   writeln('Καλημέρα φίλε ', name);
  17.   readln;
  18. end.

I'm not sure if utf8String is the appropriate type in this case but neither the String type works. Everything else is displayed just fine. Is there a solution?
Title: Re: How to save greek letters to a variable?
Post by: jamie on April 01, 2023, 03:55:38 pm
Maybe you should include also "SetConsoleCP" , too ? that sets the input.
Title: Re: How to save greek letters to a variable?
Post by: YiannisKam on April 01, 2023, 04:26:09 pm
I've tried that also. No progress.
Title: Re: How to save greek letters to a variable?
Post by: paweld on April 01, 2023, 04:59:45 pm
With LConvEncoding - you must add LCLBase to project requiments: 
Code: Pascal  [Select][+][-]
  1. program Hello;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   windows, sysutils, LConvEncoding;
  7.  
  8. var
  9.   name: String;
  10.   b: Boolean;
  11.  
  12. begin
  13.   SetConsoleOutputCP(CP_UTF8);
  14.   writeln('Πως σε λένε φίλε μου;');
  15.   readln(name);
  16.   name := ConvertEncodingToUTF8(name, GetConsoleTextEncoding, b);
  17.   writeln('Καλημέρα φίλε ', name);
  18.   readln;
  19. end.
Title: Re: How to save greek letters to a variable?
Post by: wp on April 01, 2023, 05:05:02 pm
Yes, this is not very intuitive... The only way I could get the 2nd string right was doing an explicit conversion by means of the routines in unit LConvEncoding (requires package LazUtils in case of console application) because the input codepage is 850 (setting it to UTF8 results in #0 strings after the ReadLn...). And of course - since the codepage is 850 - I cannot enter Greek characters here...
Code: Pascal  [Select][+][-]
  1. program hello;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   windows, SysUtils,
  7.   LConvEncoding;  // Add "LazUtils" to project requirements
  8.  
  9. var
  10.   name: String;
  11.   cp: Integer;
  12.   cpStr: String;
  13.  
  14. begin
  15.   SetConsoleOutputCP(CP_UTF8);
  16.   cp := GetConsoleCP;
  17.   cpStr := 'cp' + IntToStr(cp);
  18.   writeln('Πως σε λένε φίλε μου;');
  19.   Write('Enter some text: ');
  20.   readln(name);
  21.   name := ConvertEncoding(name, cpStr, 'utf-8');
  22.   writeln('Καλημέρα φίλε ', name);
  23.   Write('Press ENTER to quit...');
  24.   readln;
  25. end.

[EDIT]
paweld was faster ...  But don't add LCLBase to the requirements because this pulls in the LCL. Better to use LazUtils which does not depend on the LCL.
Title: Re: How to save greek letters to a variable?
Post by: paweld on April 01, 2023, 05:13:50 pm
But don't add LCLBase to the requirements because this pulls in the LCL. Better to use LazUtils which does not depend on the LCL.
Thank you for the information. I didn't know about that.
Title: Re: How to save greek letters to a variable?
Post by: marcov on April 01, 2023, 05:18:55 pm
Doesn't enabling utf8 in the application manifest screen work for you?



Title: Re: How to save greek letters to a variable?
Post by: YiannisKam on April 01, 2023, 05:28:52 pm
I've tried everything but nothing works so far
Title: Re: How to save greek letters to a variable?
Post by: wp on April 01, 2023, 06:44:52 pm
Delphi has the same behaviour. This is my test project usable in both Lazarus and Delphi:

Code: Pascal  [Select][+][-]
  1. program hello;
  2.  
  3. {$IFDEF FPC}
  4.  {$mode objfpc}{$H+}
  5. {$ENDIF}
  6.  
  7. uses
  8.   windows, SysUtils;
  9.  
  10. var
  11.   name: String;
  12.   i: Integer;
  13. begin
  14.   SetConsoleOutputCP(CP_UTF8);
  15.   SetConsoleCP(CP_UTF8);
  16.   writeln('Πως σε λένε φίλε μου;');
  17.   Write('Enter some text: ');
  18.   readln(name);
  19.  
  20.   Write('Bytes of "name":');
  21.   for i := 1 to Length(name) do Write(Format(' $%.2x', [ord(name[i])]));
  22.   WriteLn('; Length(name)=', Length(name));
  23.  
  24.   writeln('Καλημέρα φίλε ', name);
  25.   Write('Press ENTER to quit...');
  26.   readln;
  27. end.

It looks as if Windows accepts only ASCII character (< #128) for input when SetOutputCP(CP_UTF8) has been called; other characters are replaced by zero.
Title: Re: How to save greek letters to a variable?
Post by: YiannisKam on April 01, 2023, 07:09:54 pm
Yes, as it seems the string is zeroed out
Title: Re: How to save greek letters to a variable?
Post by: marcov on April 01, 2023, 07:29:22 pm
I also experimented (with non-greek results), and it seems that this is a problem of readfile(), for unicode one need to use readconsolew().
Title: Re: How to save greek letters to a variable?
Post by: Warfley on April 01, 2023, 08:03:21 pm
It's one of the problems I've found a few times now. Basically windows does not allow to change the input encoding to UTF-8. It's actually a really big problem for my TermUtils, which simply does not work correctly with Unicode on Windows. It's just something that Windows does not support. The "correct" way of doing it under windows is to read input as utf-16 (widestring/unicode string) and use this or convert it to utf-8 internally.
Title: Re: How to save greek letters to a variable?
Post by: pascal111 on April 01, 2023, 11:42:04 pm
It's not understood yet to me although the clarity of the code but my compiler still having no sensible reactions messages. May you provide us some details?
TinyPortal © 2005-2018