PDA

View Full Version : سوال: تبدیل سریع کارکتر اسکی به کارکتر اسکی دیگر



mbshareat
جمعه 08 دی 1402, 10:46 صبح
سلام
من یک رشته کد اسکی دارم که میخوام بعضی کارکترها رو در اون با کارکترهای دیگه جایگزین کنم. مثلاA رو B کنم.
ساده ترین روش استفاده از دو رشته و استفاده از Pos هست:
Procedure ChangeChars(Var S:String);
Var
A,B:String;
I,P:Integer;
begin
A:=#45#67#123;
B:=#46#69#130;
For I:=1 To Length(S) Do
Begin
P:=Pos(S[I],A);
If P>0 then
S[I]:=B[P];
End;
end;

اما این روش کند هست. روش دیگه تعریف همه کارکترها و جایگزینی با استفاده از کد اسکی به عنوان اندیس آرایه هست:
Procedure ChangeChars2(Var S:String);
Var
A,B:String;
I:Integer;
Ch:Array[0..255]of Chars;
begin
For I:=0 To 255 Do
Ch[I]:=Chr(I);
A:=#45#67#123;
B:=#46#69#130;
For I:=1 To Lenght(A) Do
Ch[Ord(A[I])]:=B[I];
For I:=1 To Lenght(S) Do
S[I]:=Ch[Ord(S[I])];
end;

این روش هم به نظرم سریعترین روش نیست.اگر میشد از اشاره گر PChar یا PByteArray استفاده کرد بهتر بود. ولی روشش رو بلد نیستم.
Procedure ChangeChars3(Var S:String);
Var
A,B:String;
I:Integer;
Ch256:String;
P1,P2:PChar;
begin
For I:=0 To 255 Do
Ch256:=Ch256+Chr(I);
A:=#45#67#123;
B:=#46#69#130;
For I:=1 To Length(A) Do
Ch256[Ord(A[I])]:=B[I];
P1:=PChar(S);
P2:=PChar(Ch256);
For I:=1 To Length(S) Do
P1[I]:=P2[P1[I]^];
end;

سعی کردم از PByteArray برای P2 استفاده کنم باز هم نشد!
Procedure ChangeChars4(Var S:String);
Var
A,B:String;
I:Integer;
Ch256:String;
P1:PChar;
P2:PByteArray;
begin
For I:=0 To 255 Do
Ch256:=Ch256+Chr(I);
A:=#45#67#123;
B:=#46#69#130;
For I:=1 To Length(A) Do
Ch256[Ord(A[I])]:=B[I];
P1:=PChar(S);
P2:=@Ch256;
For I:=1 To Length(S) Do
P1[I]:=P2[P1[I]];
end;

فقط میخوام Ord استفاده نکنم

mbshareat
جمعه 08 دی 1402, 22:21 عصر
نمی دونم آیا ()Ord کند بود یا نه ولی آخرش بیخیال اشاره گر شدم و به این شکل کار کرد:(Ch256 رو از یک شروع به مقدار دهی کردم که خرابکاری نشه)
Procedure ChangeChars(Var S:String);
Var
A,B:String;
I:Integer;
Ch256:String;
P1,P2:PChar;
begin
For I:=1 To 255 Do
Ch256:=Ch256+Chr(I);
A:=#65#97;//Aa
B:=#66#99;//Bc
For I:=1 To Length(A) Do
Ch256[Ord(A[I])]:=B[I];
P1:=PChar(S);
For I:=1 To Length(S) Do
S[I]:=Ch256[Byte(P1[I-1])];
end;
procedure TForm1.Button2Click(Sender: TObject);
Var
S:String;
begin
S:='Aa';
ChangeChars3(S);
ShowMessage(S);
end;


این 4 خط یک نتیجه رو میدند. فقط نمی دونم هنگام استفاده از Byte و اشاره گر PChar طول رشته تا چقدر میتونه باشه. چون ممکن هست رشته طولانی تر از 64 کیلو بایت هم داشته باشم و نمی دونم آیا همیشه یکسان هستند یا نه:

S[I]:=Ch256[Ord(S[I])];
S[I]:=Ch256[Byte(S[I])];
S[I]:=Ch256[Ord(P1[I-1])];
S[I]:=Ch256[Byte(P1[I-1])];

یوسف زالی
شنبه 09 دی 1402, 11:42 صبح
سلام. اگر رشته خیلی طولانیه از استریم استفاده کن. اگر انسی هست TIdBytes هم گزینه مناسبیه. راه زیاد داره

mbshareat
شنبه 09 دی 1402, 22:41 عصر
ممنونم. تعدادی سوال ساده برام پیش اومد.
استفاده تابع Byte رو درست نفهمیدم.ظاهرا در رشته هم ارز Ord هست اما Ord در متغیرهای تعریف کاربر هم کاربرد داره.اسم این نوع متغیر چیه؟:
Type A=(Red,Blue,Green);
چرا اگر رشته S داشته باشیم، PChar(S) با S@ برابر نیست؟( Byte(S[1]) نتیجه متفاوت میده!)
تابع Byte کم ارزشترین بایت نوع عدد صحیح رو برمی گردونه؟