Есть ли версия ANSI для копирования? - PullRequest
12 голосов
/ 19 мая 2011

В Delphi XE существует ли версия ANSI для копирования? Я много использую Copy для копирования частей строк ANSI.

Ответы [ 3 ]

19 голосов
/ 19 мая 2011

Altar функция Copy в Delphi - это встроенная функция, которая обрабатывается компилятором, а не исполняемой библиотекой.в зависимости от параметров, переданных этой функцией, вызовите внутренние функции LStrCopy или UStrCopy

, проверьте этот пример:

{$APPTYPE CONSOLE}

uses
  SysUtils;
Var
   s : AnsiString;
   u : string;
begin
  try
   s:='this is a ansi string';
   s:= Copy(s,1,5);
   Writeln(s);
   u:='this is a unicode string';
   u:= Copy(u,1,5);
   Writeln(u);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

Теперь проверьте код сборки

Project91.dpr.12: s:='this is a ansi string';
004111DC B8787E4100       mov eax,$00417e78
004111E1 BA04134100       mov edx,$00411304
004111E6 E8314FFFFF       call @LStrAsg
Project91.dpr.13: s:= Copy(s,1,5);
004111EB 68787E4100       push $00417e78
004111F0 B905000000       mov ecx,$00000005
004111F5 BA01000000       mov edx,$00000001
004111FA A1787E4100       mov eax,[$00417e78]
004111FF E8A050FFFF       call @LStrCopy //call the ansi version of copy
Project91.dpr.14: Writeln(s);
00411204 A1EC2C4100       mov eax,[$00412cec]
00411209 8B15787E4100     mov edx,[$00417e78]
0041120F E84033FFFF       call @Write0LString
00411214 E8DF33FFFF       call @WriteLn
00411219 E8D22AFFFF       call @_IOTest
Project91.dpr.15: u:='this is a unicode string';
0041121E B87C7E4100       mov eax,$00417e7c
00411223 BA28134100       mov edx,$00411328
00411228 E8534EFFFF       call @UStrAsg
Project91.dpr.16: u:= Copy(u,1,5);
0041122D 687C7E4100       push $00417e7c
00411232 B905000000       mov ecx,$00000005
00411237 BA01000000       mov edx,$00000001
0041123C A17C7E4100       mov eax,[$00417e7c]
00411241 E8C654FFFF       call @UStrCopy //call the unicode version of copy
Project91.dpr.17: Writeln(u);
00411246 A1EC2C4100       mov eax,[$00412cec]
5 голосов
/ 19 мая 2011

Копирование - это «волшебная процедура» компилятора, она обрабатывается встроенным компилятором в зависимости от того, какие параметры вы передаете (строка ANSI, строка или динамический массив). Вы можете просто использовать Copy; он будет правильно работать со строками ANSI.

0 голосов
/ 19 июля 2013

У меня та же проблема, см. Этот код:

const
     TheStart=13;
     TheEnd=69;
type
    TMyFileField: Array[TheStart..TheEnd] of Char; // This is a simplification of a field type on a file
procedure WriteWideStringToArrayOfChars(TheLiteral:WideString);
var
   MyFileField:TMyFileField; // This is a simplification, it is really a Field inside a File
   MyIndex:Integer;
begin
     for MyIndex:=1 to Max(Length(TheLiteral),1+TheEnd-TheStart)
     do begin // Will copy as many charactes as possible from TheLiteral to MyFileField
             MyFileField[MyIndex]:=Copy(TheLiteral,MyIndex,1)[1]; // This gives Copile Error: Incompatible types 'Char' and 'WideChar'
        end;
end;

Проблема в том, что WideString должен быть сохранен в массив Ar Char of Char внутри файла. Таким образом, типы смешивания должны быть выполнены ... и, таким образом, произойдет некоторая потеря символов Unicode, и никак не избежать этого.

Требуется: компилятор может скомпилировать его.

Solution1: конвертировать WideString в String до вызова Copy или внутри Copy. Решение 2. Преобразуйте WideChar в Char перед заданием.

Вот оба решения (помните, что некоторые символы Юникода могут быть потеряны) ...

Solution1:

MyFileField[MyIndex]:=Copy(UTF8Encode(TheLiteral),MyIndex,1)[1]; // Note: Unicode chars will not get lost, but converted, so beware of accent vocals, etc...

или

MyFileField[MyIndex]:=Copy(String(TheLiteral),MyIndex,1)[1]; // Note: Unicode chars will get lost, they will be converted to '?'

1021 * * Solution2:

MyFileField[MyIndex]:=Char(Copy(TheLiteral,MyIndex,1)[1]); // Note: Unicode chars will get lost, they will be converted to '?'

Если кто-нибудь знает муравейник лучше, я был бы рад узнать.

Я лично использую Copy(String(Literal),Start,NumberOfChars), так как нормальные буквы с акцентом сохраняются и, что более важно, длина ...

Пример: длина (строка ('BlaBlaBlá')) -> 9 Пример: длина (UTF8Encode ('BlaBlaBlá')) -> более 9 с момента последнего 'á' преобразуется в несколько символов и т. Д ...

Надеюсь, это кому-нибудь поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...