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

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

Похожие вопросы