D
D
Danil2019-05-05 19:48:27
Pascal
Danil, 2019-05-05 19:48:27

How to set encoding for Russian text output in TMemo field?

The code works like this:
When I, by clicking on the button, launch the procedure procedure TfMain.ButtonEncryptClick(Sender: TObject) , the text from the Memo1 field is read and then processed mainly by the encr_decr function . At the end, the ciphertext is displayed in the Memo2 field using the magic square method. So, the code works well only with English characters, if you enter Russian text in Memo1 , then on the output in Memo2 we get krakazyabry and question marks.
I have suggestions that the delete function and the swap procedure may be to blame . But rewriting deleteI did not get the expected result, and even errors started to fly out, as a result I returned back to the delete function . Instead of delete , I wrote the code:

for num:=1 to UTF8Length(s)-n*n do
  sdel:= sdel + s[num+n*n];
s:= sdel;

I've been smoking forums for two days, but I still don't understand how to solve the problem. It might be worth rewriting the swap procedure somehow , which works with symbols, but there is no idea what to change there and whether it should be touched at all.
unit main;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, LazUTF8, LConvEncoding, StdCtrls;

type

  mas=array[1..10,1..10] of integer;

  { TfMain }

  TfMain = class(TForm)
    ButtonEncrypt: TButton;
    ButtonDecrypt: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    MemoMS: TMemo;
    procedure ButtonDecryptClick(Sender: TObject);
    procedure ButtonEncryptClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private

  public

  end;

var
  fMain: TfMain;
  A:mas;
  i,j,n,k:integer;
  lgthS:real;
  s:string;

implementation

{$R *.lfm}

{ Programm }

procedure kvadrat(var A:mas;n:integer);
var
  i,j:integer;
begin
  for i:= 1 to n do
    for j:= 1 to n do begin
       a[i,j]:=  1+((i+j-1+n div 2) mod n)*n+(i+2*(j-1)) mod n;
    end;
end;

procedure swap(var c1,c2:char);
var
  s2:char;
begin
  s2:= c1;
  c1:= c2;
  c2:= s2;
end;

function encr_decr(A:mas;stroka:string;enc_dec:boolean):string; // квадрат,строка,true-шифруем,false-расшифровываем
var
  i,j,k,num:integer;
  l:array[1..100] of integer;
  sc,s1,s,sdel:string;
  s2:char;
begin
  s:= stroka;
  k:= 0;
  sdel:= '';
  for i:= 1 to n do
    for j:= 1 to n do
      begin
        k:= k+1;
        l[k]:= A[i,j];
      end;
  if n*n>Length(s) then while Length(s)<n*n do s:= s+' ';
  if Length(s) mod (n*n)>0 then while (Length(s) mod (n*n))>0 do s:= s+' ';
  sc:= '';
repeat
  s1:= Copy(s,1,n*n);
  if enc_dec then for i:= 1 to n*n do swap(s1[i],s1[l[i]])
             else for i:= n*n downto 1 do swap(s1[i],s1[l[i]]);
    Delete(s,1,n*n);
    sc:= sc+s1;
until UTF8Length(s)<=1;
encr_decr:= sc;
end;

{ TfMain }

procedure TfMain.FormCreate(Sender: TObject);
begin
end;

procedure TfMain.ButtonEncryptClick(Sender: TObject);
var
  str: string;
begin
  s:= Memo1.Text;
  lgthS:= UTF8Length(s);
  lgthS:= sqrt(lgthS);
  n:= round(lgthS);
  if n= lgthS then lgthS:= trunc(lgthS)
    else lgthS:= trunc(lgthS)+1;
  if lgthS<3 then lgthS:= 3;
  if round(lgthS) and 1 = 0 then lgthS:= lgthS+1;
  n:= round(lgthS);

  kvadrat(A,n); // расчет квадрата
  MemoMS.Clear;
  str:= '';
  for i:= 1 to n do begin
    for j:= 1 to n do begin
      str:= str + '   ' + IntToStr(A[i, j]);
    end;
    MemoMS.Lines.Add(str);
    str:= '';
  end;

  Memo2.Text:= ( encr_decr(A,s,true) );
end;

procedure TfMain.ButtonDecryptClick(Sender: TObject);
begin
end;

end.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Danil, 2019-05-06
@OnlyGoRush

Found an answer to your question. In order for the encoding to be displayed as it should, it is necessary to rename all string and char data types to widestring and widechar . Thus, two bytes will be allocated for each character instead of one.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question