动态数组的使用问题(100分)

  • 主题发起人 主题发起人 阿伟~
  • 开始时间 开始时间

阿伟~

Unregistered / Unconfirmed
GUEST, unregistred user!
type
buf=array of char
var
buf1:buf;
begin
setlength(buf1,2)
buf1[0]:='@';
buf1[1]:='2'
edit1.text:=string(copy(buf1,1,1))
end
为什么在EDIT框里显示的不是我要的2而是2&E呢?是不是我哪些地方搞错了?
 
这应该是个简单的问题吧对于大虾们来说,怎么没人顶呢?
 
刚才在D7上试了一下
确实会出现一些不想要的东西
估计是Delphi进行类型转换时出了一点问题

edit1.text:=string(copy(buf1,1,1))
改成
edit1.text:=copy(string(buf1),2,1);
试试
在D7上已经通过
 
Unit

System

Category

string handling routines

function Copy(S; Index, Count: Integer): string;
function Copy(S; Index, Count: Integer): array;

Description

S is an expression of a string or dynamic-array type. Index and Count are integer-type expressions. Copy returns a substring or sub array containing Count characters or elements starting at S[Index].

If Index is larger than the length of S, Copy returns an empty string or array.

If Count specifies more characters or array elements than are available, only the characters or elements from S[Index] to the end of S are returned.

Note: When S is a dynamic array, Copy can only be used as a parameter in a call to a procedure or function that expects an array parameter. That is, it acts like the Slice function when working with dynamic arrays.
 
to Mike1234567890
谢谢我这调试也通过了,但我有点弄不明白的是
我如果这样声明一个动态的CHAR数组占用的内存:
SetLength(buf1,9);
buf1[0]:='@';
buf1[1]:='2';
那么 edit1.Text:=string(copy(buf1,2,1));
却又没问题,再也不会出现我不想要的数据了,但我理解是,既然是动态的数组那么分配的内存应该更合理才行,如果这样的话不是有点浪费了?(另:我如果把SET的地方长度改为8,那么结果还是不行,只有9和9以上才行)
 
好用就行
有时候咱们不能把所有问题都追究到底
String其实是一个结构
估计是Delphi在内部转换时处理时有特殊情况
 
COPY函数中字符串或者数组中的第一位索引不是0而是1
 
呵呵,因为edit1.Text:=string(copy(buf1,2,1));后'2'后面没有字符串结束符,
PChar,string类型是以一个''来判断字符串结束的,而array of char是没有的,于是就
出现你那样的转换结果。SetLength(buf1,9);就把'2'后面的字符清成''了,所以没有问题。
 
呵呵,STRING 从1开始我是知道的

我只想知道的更多点呵呵,我在查下资料,顺便看看还有无高人发表见解,半个小时后就散分了[:D]
 
to nicai_wgl
对,理论上是这样的,但我不明白的是,如果是这样的话那么我只要初始化内存的时候分配的大一点点就可以,比如:
SetLength(buf1,3);
buf1[0]:='@';
buf1[1]:='2';
但为什么非要9和9以上才不会出现问题呢?
 
做人嘛,有时候还是需要不求甚解的!
 
呵呵,也许当我忙的时候我会顾不了挖这么深了,但闲暇的时候嘛呵呵,我也怕以后有小弟问起我个所以然来,我都不知道如何应付,寒啊~~~~~~~~~~
 
Note: When S is a dynamic array, Copy can only be used as a parameter in a call to a procedure or function that expects an array parameter. That is, it acts like the Slice function when working with dynamic arrays.
 
type
buf=array of char
var
buf1:buf;
begin
setlength(buf1,2)
buf1[0]:='@';
buf1[1]:='2'
edit1.text:=string(copy(buf1,1,1))=>edit1.text:=string(copy(pchar(buf1),1,1))
end
 
你只要告诉他怎么用能正确就可以了
 
多人接受答案了。
 
procedure TForm1.Button1Click(Sender: TObject);
var
buf1: array of char;
TmpStr: string;
TmpOrd: Word;
begin
SetLength(buf1, 2);
buf1[0] := '@';
buf1[1] := '2';
TmpStr := string(copy(buf1, 1, 1));
//TmpOrd := Ord(TmpStr[1]);
Edit1.Text := TmpStr;
//ShowMessage(IntToStr(TmpOrd));
ShowMessage(Edit1.Text);
end;

更正:
问题并不是出在TmpStr := string(copy(buf1, 1, 1));而是出在Edit1.Text := TmpStr; 因为ShowMessage(string(copy(buf1, 1, 1)));是正确的,Edit1.Text在赋值后指针没改,说明是复制了字符串,而不是引用了字符串。 跟进DCU看Edit1.Text := TmpStr;执行了下列函数:

procedure TControl.SetTextBuf(Buffer: PChar);
begin
Perform(WM_SETTEXT, 0, Longint(Buffer)); //这句拷贝了字符串,引起出错。
Perform(CM_TEXTCHANGED, 0, 0);
end;

procedure TControl.DefaultHandler(var Message);
var
P: PChar;
begin
with TMessage(Message) do
case Msg of
...
WM_SETTEXT:
begin
P := StrNew(PChar(LParam)); //这句复制字符串
StrDispose(FText);
FText := P;
SendDockNotification(Msg, WParam, LParam);
end;
end;
end;

function StrNew(const Str: PChar): PChar;
var
Size: Cardinal;
begin
if Str = nil then Result := nil else
begin
Size := StrLen(Str) + 1; //这句查找字符串结束符来计算字符长度,并加1。
Result := StrMove(StrAlloc(Size), Str, Size); //拷贝字符。
end;
end;
 
总结:
1、TmpStr := string(copy(buf1, 1, 1));执行后TmpStr并不是标准的String(没有结束符);
2、Edit1.Text := TmpStr;字符串复制使1中的错误暴露出来。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
625
import
I
I
回复
0
查看
316
import
I
后退
顶部