OnlyGoRush
@OnlyGoRush
Студент

Как настроить кодировку для вывода русского текста в поле TMemo?

Код работает так:
Когда я, нажимая на кнопку, запускаю выполнение процедуры procedure TfMain.ButtonEncryptClick(Sender: TObject), то из поля Memo1 считывается текст и затем обрабатывается в основном функцией encr_decr. По окончанию в поле Memo2 выводится зашифрованный текст методом магического квадрата. Так вот, код хорошо работает только с английскими символами, если вписать в Memo1 русский текст, то на выводе в Memo2 получаем краказябры и знаки вопроса.

У меня есть предположения, что в этом могут быть виноваты функция delete и процедура swap. Но переписав delete я не получил ожидаемого результата, да еще и ошибки начали вылетать, в итоге вернулся обратно на функцию delete. Вместо delete я писал код:
for num:=1 to UTF8Length(s)-n*n do
  sdel:= sdel + s[num+n*n];
s:= sdel;


Курю форумы уже два дня, но так и не понимаю, как решить проблему. Возможно, стоит как-то переписать процедуру swap, которая работает с символами, но нет никаких представлений что там менять и надо ли вообще ее трогать.

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.
  • Вопрос задан
  • 349 просмотров
Решения вопроса 1
OnlyGoRush
@OnlyGoRush Автор вопроса
Студент
Нашел ответ на свой вопрос. Чтобы кодировка отображалась как надо, необходимо все типы данных string и char переименовать на widestring и widechar. Таким образом на каждый символ будет выделено по два байта вместо одного.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы