Не могу разобраться с WideCompareText

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

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

Не могу разобраться с WideCompareText

Сообщение mrkaban » 20.08.2016 08:35:24

Здравствуйте, сразу предупреждаю, что я совсем новичок. Помогите пожалуйста разобраться. Нашел WideCompareText, и с её помощью пытаюсь сравнить названия программ с базой в текстовом файле.

Основной вопрос в этих двух строках
Result:= WideCompareText(UTF8ToSys(s), UTF8ToSys(d));
if not Result=(0) then break
Тут я пытаюсь сравнить две переменные, в которые считывает строки из текстового файла, и соответственно результат сравнения присваиваем переменной Result. Прочитал, что 0 означает совпадение. И далее пытался сделать условие, что если совпало, тогда записываем в таблицу.

Суть проблемы в том, что с Result=(0) он ничего не записывает в таблицу, если поставить 1 или -1, тогда он просто либо всё подряд записывает, либо случайным образом.

Ниже приведу полностью код процедуры
Код: Выделить всё
procedure TfMian.Button1Click(Sender: TObject);
var
   MyList: TStringList;
   MyRegistry: TRegistry;
   i: Integer;
   Str: string;
   install: TextFile;
   TempStr: String;
   //копипаст для заполнения таблицы
     s: WideString;   // читаем из install
     d: WideString;   // читаем из NameProgramm в d
     f: string;   // читаем из Rasprost
     g: string;   // читаем из License
     h: string;  // читаем из Stoimost
     j: string;  // читаем из Zamena
     k: integer; // для заполнения данных
     Result: integer; // для сравнения
     for1: integer;

begin
Cursor:= crHourGlass;
bSearch.Visible:=False;
Button1.Visible:=False;
//Получаем список установленных программ
     MyRegistry:=TRegistry.Create;
     MyList:=TStringList.Create;
     AssignFile(install, UTF8ToSys('install.txt'));
     ReWrite(install);
         with MyRegistry do
            begin
            RootKey:=HKEY_LOCAL_MACHINE;
            if OpenKey('Software\Microsoft\Windows\CurrentVersion\Uninstall',
            False)=True then GetKeyNames(MyList);   // получает ключи в переменную mylist
            TempStr := MyList.Text;           // преобразуем в string
            Writeln(install, TempStr); //записываем в файл
            CloseKey;
              end;
         CloseFile(install);
          try
// подключаем текстовые файлы для дальнейшей работы с ними
      AssignFile(install, UTF8ToSys('install.txt'));
      Reset(install);
      AssignFile(NameProgramm, UTF8ToSys('NameProgramm.txt'));
      Reset(NameProgramm);
      AssignFile(Rasprost, UTF8ToSys('Rasprost.txt'));
      Reset(Rasprost);
      AssignFile(License, UTF8ToSys('License.txt'));
      Reset(License);
      AssignFile(Stoimost, UTF8ToSys('Stoimost.txt'));
      Reset(Stoimost);
      AssignFile(Zamena, UTF8ToSys('Zamena.txt'));
      Reset(Zamena);
          //делаем, пока не конец файла:
       while not Eof(install) do begin

            Cursor:= crHourGlass;
            Readln(install, s); //читаем в s очередную строку
            Readln(NameProgramm, d);
            Readln(Rasprost, f); //читаем в f очередную строку
            Readln(License, g);
            Readln(Stoimost, h);
            Readln(Zamena, j);
//пытаемся сравнить, и результат записать
               Result:= WideCompareText(UTF8ToSys(s), UTF8ToSys(d));
               if not Result=(0) then break
              else begin
         // далее нужно записать что нашли в таблицу
                 StringGrid1.RowCount:= StringGrid1.RowCount + 1;
                 k:= StringGrid1.RowCount;
                 SetLength(d, (k * 15));
                 StringGrid1.Cells[0, StringGrid1.RowCount-1]:= s;
                 StringGrid1.Cells[1, StringGrid1.RowCount-1]:= f;
                 StringGrid1.Cells[2, StringGrid1.RowCount-1]:= g;
                 StringGrid1.Cells[3, StringGrid1.RowCount-1]:= h;
                 StringGrid1.Cells[4, StringGrid1.RowCount-1]:= j;
              end;

              end;
   finally
      CloseFile(install);
      CloseFile(NameProgramm);
      CloseFile(Rasprost);
      CloseFile(License);
      CloseFile(Stoimost);
      CloseFile(Zamena);
      Cursor:= crDefault;
   end;  //try
end;                                         


Заранее благодарен!
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Не могу разобраться с WideCompareText

Сообщение serge#LVL » 20.08.2016 10:56:33

По-моему, у вас ошибка в выражении
Код: Выделить всё
Result:= WideCompareText(UTF8ToSys(s), UTF8ToSys(d));
if not Result=(0) then break

Вообще, break используется при выходе из циклов for, while, repeat. if ... then - это не цикл
сделайте просто
Код: Выделить всё
if Result=0 then

Потом, возможно, у вас неявное преобразование типов. UTF8ToSys возвращает тип string=AnsiString, а вы пытаетесь сравнить widestring. Нужно использовать или AnsiCompareText(), или приводить к типу Result:= WideCompareText( widestring(UTF8ToSys(s)), widestring(UTF8ToSys(d)) );или использовать другую функцию преобразования, в зависимости, что нужно сделать.

Вот простой тест.

Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
  s: WideString;
  d: WideString;
  Result: int64;
begin
  s:=widestring(UTF8ToSys('строка Ы'));
  //d:=s; // d=s
  //d:=widestring(UTF8ToSys('строка Я')); // s<d
  d:=widestring(UTF8ToSys('строка А')); // s>d
  Result:= WideCompareText(s, d);
  if Result=0 then ShowMessage('s=d')
  else if Result<0 then ShowMessage('s<d')
  else if Result>0 then ShowMessage('s>d');
end;
serge#LVL
новенький
 
Сообщения: 13
Зарегистрирован: 19.08.2016 13:17:36

Re: Не могу разобраться с WideCompareText

Сообщение mrkaban » 20.08.2016 11:15:29

Изменил две строки на
Result:= WideCompareText( widestring(UTF8ToSys(s)), widestring(UTF8ToSys(d)) );
if Result=0 then begin

Но не помогло=((( если нужно могу весь код выложить.

Он записывает пустую строку
Изображение

если ставлю if Result=1 then тогда он записывает случайные строки. Я решил, что раз записывает, значит ошибка именно в механизме сравнения.
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Не могу разобраться с WideCompareText

Сообщение Лекс Айрин » 20.08.2016 11:47:05

А зачем столько преобразований? Не легче ли сравнить S и D, а потом результат преобразовать как нужно?
И, кстати, попробуй заменить UTF8ToSys, на UFF8ToCP1251, если я правильно помню, то она может выдавать некорректный результат.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Не могу разобраться с WideCompareText

Сообщение mrkaban » 20.08.2016 12:04:57

Изменил на
Код: Выделить всё
     AssignFile(install, 'install.txt');
      Reset(install);
      AssignFile(NameProgramm, 'NameProgramm.txt');
      Reset(NameProgramm);
      AssignFile(Rasprost, 'Rasprost.txt');
      Reset(Rasprost);
      AssignFile(License, 'License.txt');
      Reset(License);
      AssignFile(Stoimost, 'Stoimost.txt');
      Reset(Stoimost);
      AssignFile(Zamena, 'Zamena.txt');
      Reset(Zamena);
          //делаем, пока не конец файла:
       while not Eof(install) do begin

            Cursor:= crHourGlass;
            Readln(install, s); //читаем в s очередную строку
            Readln(NameProgramm, d);
            Readln(Rasprost, f); //читаем в f очередную строку
            Readln(License, g);
            Readln(Stoimost, h);
            Readln(Zamena, j);

            Result:= WideCompareText( widestring(s), widestring(d) );
               if Result=0 then begin
         // далее нужно записать что нашли
                 StringGrid1.RowCount:= StringGrid1.RowCount + 1;
                 k:= StringGrid1.RowCount;
                 SetLength(d, (k * 15));
                 StringGrid1.Cells[0, StringGrid1.RowCount-1]:= UTF8ToSys(s);
                 StringGrid1.Cells[1, StringGrid1.RowCount-1]:= UTF8ToSys(f);
                 StringGrid1.Cells[2, StringGrid1.RowCount-1]:= UTF8ToSys(g);
                 StringGrid1.Cells[3, StringGrid1.RowCount-1]:= UTF8ToSys(h);
                 StringGrid1.Cells[4, StringGrid1.RowCount-1]:= UTF8ToSys(j);
              end;                                                           


Но не помогло =(( не понимаю, почему вообще ни одного результата?

Кодировку поставил UTF8ToSys, так как с 1251 некорректно отображает, а с ней вроде нормально отображает. Если сделать if Result=1 then begin , тогда записывает нормально, но не то))))))
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Не могу разобраться с WideCompareText

Сообщение Лекс Айрин » 20.08.2016 13:09:17

mrkaban писал(а):Но не помогло =(( не понимаю, почему вообще ни одного результата?


А ты учитываешь, что в винде регистронезависимые имена файлов, и что их надо приводить к одному регистру, если сравниваешь имена файлов?
mrkaban писал(а):Кодировку поставил UTF8ToSys, так как с 1251 некорректно отображает, а с ней вроде нормально отображает.


так может дело в том, что у тебя просто другая кодировка? Попробуй отобразить ShowMessage с разными вариантами кодировок.
serge#LVL писал(а):if Result=0 then ShowMessage('s=d')
else if Result<0 then ShowMessage('s<d')
else if Result>0 then ShowMessage('s>d');


А это разве корректный код? :shock: может тогда проще использовать case?
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Не могу разобраться с WideCompareText

Сообщение mrkaban » 20.08.2016 13:20:40

Лекс Айрин писал(а):
mrkaban писал(а):
mrkaban писал(а):Кодировку поставил UTF8ToSys, так как с 1251 некорректно отображает, а с ней вроде нормально отображает.


так может дело в том, что у тебя просто другая кодировка? Попробуй отобразить ShowMessage с разными вариантами кодировок.

Я думаю, что тут проблема именно с сравнением, так как если поставить if Result=1 then , тогда он просто всё из базы записывает, и отображается правильно.

Лекс Айрин писал(а):
mrkaban писал(а):Но не помогло =(( не понимаю, почему вообще ни одного результата?


А ты учитываешь, что в винде регистронезависимые имена файлов, и что их надо приводить к одному регистру, если сравниваешь имена файлов?


На компьютере имеется программа Artisteer, в файл куда выгружается список установленных программ она пишется так "Artisteer 4", в базе была написана просто Artisteer, изменил на Artisteer 4, но не помогло.
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Не могу разобраться с WideCompareText

Сообщение Лекс Айрин » 20.08.2016 13:35:08

mrkaban писал(а):в файл куда выгружается список установленных программ она пишется так "Artisteer 4", в базе была написана просто Artisteer, изменил на Artisteer 4, но не помогло


Тут еще куча вариантов... для примера:
А -- латинская или русская
е -- латинская или русская
пробел один или 2-3?
А может, вообще пробел не нужен...

такие вещи надо, для начала, проверять на [зачеркнуто]кошках[/зачеркнуто] четко известных данных.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Не могу разобраться с WideCompareText

Сообщение mrkaban » 20.08.2016 14:06:26

Лекс Айрин писал(а):
mrkaban писал(а):в файл куда выгружается список установленных программ она пишется так "Artisteer 4", в базе была написана просто Artisteer, изменил на Artisteer 4, но не помогло


Тут еще куча вариантов... для примера:
А -- латинская или русская
е -- латинская или русская
пробел один или 2-3?
А может, вообще пробел не нужен...

такие вещи надо, для начала, проверять на [зачеркнуто]кошках[/зачеркнуто] четко известных данных.

я специально из файла со списком программ скопировал название этой программы и вставил в базу, благо текстовая бд позволяет это сделать даже новичку))
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18


Вернуться в Lazarus

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 236

Рейтинг@Mail.ru