В Delphi XE есть ли версия ANSI для копирования? Я использую Копировать много, чтобы скопировать фрагменты строк ANSI.
Есть ли версия ANSI для копирования?
Ответ 1
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]
Ответ 2
Копировать - это "магия компилятора", она обрабатывается компилятором в основном в зависимости от параметров, которые вы передаете (строка ANSI, строка или динамический массив). Вы можете просто использовать Копировать; он будет корректно работать с ANSI-строками.
Ответ 3
У меня такая же проблема, см. этот код:
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 должен быть сохранен в am массиве Char внутри файла. Таким образом, типы смешивания должны быть выполнены... и так, некоторые свободные символы Unicode будут иметь место, не удастся избежать этого.
Требуется: компилятор может скомпилировать его.
Решение1: Преобразовать WideString в String до вызова Copy или внутри Copy. Решение2: конвертируйте WideChar в Char до появления.
Вот оба решения (помните, что некоторые символы Unicode могут потеряться)...
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 '?'
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)
, так как нормальные буквы акцента сохраняются и важнее, длина...
Пример: Length (String ('BlaBlaBlá')) → 9 Пример: длина (UTF8Encode ('BlaBlaBlá')) → Больше, чем 9, поскольку последняя 'á' преобразуется в несколько символов и т.д.
Надеюсь, это поможет кому-то!