Не работает сравнение символов.

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Не работает сравнение символов.

Сообщение purple_goth » 07.06.2012 15:30:41

уже скурил все темы какие мог. Но проблему решить не могу.
Суть такова! из Edit1 берется символ типа стринг. И сравнивается со списком символов из файла, ниже выводит статистику. Но проблема в том что с кириллицей не происходит ничего, а с латиницей все работает.

Лазарь 0.9.30.4 под Шиндой.

Код: Выделить всё
procedure TForm1.BitBtn4Click(Sender: TObject);
var vb,d:string;
  i:integer;
  eg:real;
begin
  vb:=Edit1.Text;

  for i:=Low(a) to High(a) do
     begin
[b]       if vb=Utf8ToSys(a[i])then[/b] //вот в вб пишется из edit1 a[i] записано из файла. При записи символов из a[] все русские символы отображаются нормально. =\
        begin
          eg:=num[i]/ss;
          str(eg:0:6,d);
          Label9.caption:= inttostr(num[i]);
          label10.caption:=d;
        end;
     end;
end;             
purple_goth
незнакомец
 
Сообщения: 2
Зарегистрирован: 07.06.2012 14:34:43

Re: Не работает сравнение символов.

Сообщение SSerge » 07.06.2012 15:55:04

И опять же, ссылка на Прикладную Кадаврологию: http://sirserge.altai.info/articles/?id=41 :D
Нельзя сравнивать строки и элементы строк UTF8 с байтовым типом char. Впрочем, пока не покажете как именно читаете массив a[] из файла и что именно этот массив собой представляет, остается только гадать о причинах...
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Не работает сравнение символов.

Сообщение purple_goth » 07.06.2012 15:59:54

cуть в том что при f=f все ок сравнивается, а при ф=ф нифига не происходит.
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Buttons;

type

  { TForm1 }

  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    BitBtn3: TBitBtn;
    BitBtn4: TBitBtn;
    Edit1: TEdit;
    Label10: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Opens: TBitBtn;
    Label2: TLabel;
    Label1: TLabel;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn4Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Label1Click(Sender: TObject);
    procedure Label2Click(Sender: TObject);
    procedure LabeSClick(Sender: TObject);
    procedure opensClick(Sender: TObject);
    procedure savesClick(Sender: TObject);
  private
    a: array of char;
    num: array of integer;
    ss: integer;
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.opensClick(Sender: TObject);
var
  f1: TextFile;
  i:integer;
  o: string;
  l: char;
  t: boolean;
begin
   if OpenDialog1.Execute then
   begin
     o:=OpenDialog1.FileName;
     AssignFile(f1,o);
     Reset(f1);
     ss:=0;
     while not EOF(f1) do
     begin
       t:=false;
       read(f1, l);
       if l<>' ' then
           Inc(ss)
           else
           if l=' ' then
              inc(ss);

       for i:=Low(a) to High(a) do
         if a[i]=l then
         begin
           Inc(num[i]);
           t:=true;
         end;
         if not t then
         begin
           SetLength(a, Length(a)+1);
           SetLength(num, Length(num)+1);
           a[High(a)]:=l;
           num[High(num)]:=1;
         end;
     end;
   end;
   Label1.Caption:=('Открыт фаил: '+ OpenDialog1.FileName);
   Label4.caption:=inttostr(ss);
   Label3.Visible:= true;
   Label4.Visible:= true;
     Label7.Visible:= true;
     Label8.Visible:= true;
     Label9.Visible:= true;
     Label10.Visible:= true;
     Edit1.visible:=true;
CloseFile(f1);
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
   Form1.Close;
end;

procedure TForm1.BitBtn4Click(Sender: TObject);
var vb,d:string;
  i:integer;
  eg:real;
begin
  vb:=ansitoutf8(Edit1.Text);

  for i:=Low(a) to High(a) do
     begin
       if vb=a[i]then
        begin
          eg:=num[i]/ss;
          str(eg:0:6,d);
          Label9.caption:= inttostr(num[i]);
          label10.caption:=d;
        end;
     end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     Label3.Visible:= false;
     Label4.Visible:= false;
     Label5.Visible:= false;
     Label7.Visible:= false;
     Label8.Visible:= false;
     Label9.Visible:= false;
     Label10.Visible:= false;
     Edit1.visible:=false;

end;

procedure TForm1.FormShow(Sender: TObject);
begin

end;

procedure TForm1.Label1Click(Sender: TObject);
begin

end;

procedure TForm1.Label2Click(Sender: TObject);
begin

end;



procedure TForm1.LabeSClick(Sender: TObject);
begin

end;

procedure TForm1.savesClick(Sender: TObject);
var
  f2: TextFile;
  s: string;
  i: integer;
begin
   if SaveDialog1.Execute then
   begin
     s:=SaveDialog1.FileName;
     AssignFile(f2,s);
     Rewrite(f2);
     writeln(f2,'Symb in file = ',ss);
     writeln(f2,'Symb     Abs    Otn');
     for i:=Low(a) to High(a) do
     begin
       writeln(f2, '"', a[i], '"      ', num[i], '     ', num[i]/ss);
     end;

   end;
    Label2.Caption:=('Сохраненный фаил: '+ SaveDialog1.FileName);
   CloseFile(f2);
end;
end.
purple_goth
незнакомец
 
Сообщения: 2
Зарегистрирован: 07.06.2012 14:34:43

Re: Не работает сравнение символов.

Сообщение SSerge » 07.06.2012 18:03:36

Суть в том, что читая из файла русскую букву "ф" в переменную типа char, в этой самой переменной вы получаете первый байт UTF8, то есть префикс, фактически одинаковый для всех знаков в UTF. Это если файл у вас в UTF8. Если же файл у вас еще и в кодировке windows, то получается что вы сравниваете (внимание!) двухбайтовую строку с однобайтовым символом, де еще и закодированным другим методом.

Текст по ссылке прочите все же :) Проникнитесь, наконец, что такое UTF, и почему типа char для вас больше не должно существовать. Либо пробуйте использовать WideString (если оно еще правильно сработает).

Кстати, if vb=Utf8ToSys(a[i])then скорее должно быть vb=SysToUtf8(a[i]) (применяете функцию обратного направления, байтом не может быть представлен символ UTF8, за исключением латиницы)
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Majestic-12 [Bot] и гости: 255

Рейтинг@Mail.ru
cron