String[255]在高版本Delphi里还是被解释成Byte,总体长度256,使用StrPCopy可以给Array String拷贝字符串

学了好多不了解的知识:

procedure TForm1.Button1Click(Sender: TObject);
var
  s1 : String;
  s2 : String[255];
begin
  s1:=‘ç1很好‘;
  ShowMessage(s1); // 这里显示正常
  s2:=s1;
  ShowMessage(s2); // 这里显示乱码。
  // 问这个问题的原因是,在一个recode pack 里定义了String[255],但是使用Unicode字符给它赋值的时候,就乱码了,这该怎么办?
  // 原因是String[255]还是被翻译成单字节字符,即使在Delphi 2010里也是如此
  // 有没有办法定义一个类似 s2: UnicodeString[255]; 或者s2: WideString[255]这样的东西,好放在record里面使用
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  S: ShortString;   { 255个字符长度,256个字节}
  S1: String[255];  { S1和S的字符类型一样,通过使用String声明字符串并且在String后面用中括号规定字符个数的形式定义字符串}
  Len: Integer;
begin
  S := ‘Hello‘;
  Len := Ord(S[0]); { Len现在包含S的长度为5,Ord函数可以把一个字符类型转换为整数类型}
  ShowMessage(IntToStr(Len));
  Len := SizeOf(S); { Len现在包含的是ShortString类型的大小,为256字节,并不是字符串的长度}
  ShowMessage(IntToStr(Len));
  ShowMessage(IntToStr(Length(s1)));
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  DirName    :Array [0..255] of Char;
  myname : String;
begin
  myname := ‘very good‘;
//  DirName := myname; // 这里赋值通不过
//  DirName := PChar(myname); // 这里赋值通不过
// PAnsiChar StrPCopy(PAnsiChar Dest, const AnsiString Source);
// PWideChar StrPCopy(PWideChar Dest, const UnicodeString Source);
  StrPCopy(dirname, myname); //
  ShowMessage(DirName); // 这样才可以
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  S: ShortString;
  S1: String[255];
begin
  S := ‘Hello‘;
  ShowMessage(IntToStr(Length(s)));
  ShowMessage(IntToStr(Length(s1))); // 这里显示内容不定,因为S1没有进行初始化
end;

procedure TForm1.Button5Click(Sender: TObject);
var
  S: ShortString;
  S1: String[255]; // String[255]的长度,不乘以2。它还是会被翻译成Byte
  S3: String;
  S4: Array [0..255] of Char; // 并没有在前后预留什么空间
begin
  S := ‘Hello‘;
  ShowMessage(IntToStr(Length(s))); // 5
  PWord(@S)^ := 100;
  ShowMessage(IntToStr(Length(S))); // 100,因为自动管理的长度值被改了
  PWord(@S1)^ := 200;
  ShowMessage(IntToStr(Length(S1))); // 200,因为自动管理的长度值被改了

  SetLength(S3, 255);

  ShowMessage(IntToStr(SizeOf(s)));  // 256,之所以多了1,是因为有长度管理
  ShowMessage(IntToStr(SizeOf(s1))); // 256,之所以多了1,是因为有长度管理(还是最后一个字符是#0?不太可能)
  ShowMessage(IntToStr(SizeOf(s3))); // 4
  ShowMessage(IntToStr(SizeOf(s4))); // 512
  ShowMessage(s4); // 内容不定,因为没有初始化
end;

// 删掉Array里的某个字符,相当于Delete函数
procedure ArrayDelete(var pArray: array of Char; const nIndex, nCount: Integer);
begin
  // Move ( const SourcePointer; var DestinationPointer; CopyCount : Integer ) ;
  Move(pArray[nIndex + nCount], pArray[nIndex], (StrLen(pArray) - nCount + 1) * SizeOf(Char));
end;

procedure TForm1.Button6Click(Sender: TObject);
var
  a: array[0..255] of Char;
begin
  a := ‘123456789‘;
  ArrayDelete(a, 2, 3);
  ShowMessage(a);
end;

lstrcpy
你也可以用windows单元里的lstrcpy函数。
这个是windows提供的等价strcpy的函数。
性能比strcpy低,但是有异常处理。

------------------------------------------------

var
DirName : String[255]
begin
// 若干赋值
Delete(DirName, Length(DirName), 1);
end;

现在改成:
var
DirName : Array [0..254] of Char
begin
// 这个Delete应该怎么写?没有初始化的字符,默认都是#0?
end;

比方说S1是Array [0..255] of Char
目前S1的值是MyName
我就是想把最后一个字符去掉,改成MyNam

------------------------------------------------

应该是错误的办法:
move(a[1], a[0], strlen(a)*sizeof(char));
去看tlist的delete方法

可能的办法:
a[5] := 0;

聪明办法:
procedure ArrayDelete(var pArray: array of Char; const nIndex, nCount: Integer);
begin
Move(pArray[nIndex + nCount], pArray[nIndex], (StrLen(pArray) - nCount + 1) * SizeOf(Char));
end;

var
a: array[0..255] of Char;
begin
a := ‘123456789‘;
ArrayDelete(a, 2, 2);
ShowMessage(a);
end;

笨办法:
mystring:=DirName;
mystring:=LeftStr(mystring, Length(mystring)-1);
StrPCopy(DirName, mystring);

------------------------------

疑问:
1. Array数组没有用完的时候,后面的字符会被初始化成什么?什么才是字符串准确终止?
2. String可否包含#0?应该可以。另外要学会使用String的头部数据。
3. 据说AnsiString和UnicodeString可以相互赋值
4. move只是移动内存数据 不会覆盖不被移动的区域
那a这个array是如何感受到,它的字符串变短了呢?
array不是有一个前缀,这样才能知道当前array用了多长的空间

学习了:
1. 新学了StrLen、Delete函数
2. 移动开发,String下标从0开始

--------------------------------

procedure TForm1.Button7Click(Sender: TObject);
var
S1: Array [0..255] of Char;
S2: String[255];
begin
S1:=‘0123456789‘;
S1[3]:=#0;
ShowMessage(String(S1)); // 012,我估计是转换到String的时候,碰到#0就停了。但其实S1的长度仍是10

S2:=‘0123456789‘;;
Byte(S2[0]) := 3;
ShowMessage(String(S2)); // 012,修改S2的长度管理,人工强行变成只使用了3个字符。
end;

这说明,array看到#0就停止。String[255]则是有一个前缀在管理使用的长度

这样就截断字符串了,就是你说的Delete,而且不考虑删除中间

最后一个小小问题:Array有一个前缀来管理使用的长度吗?
回答:没有。但是array of Char又有了。

--------------------------------

type
T = packed record
A: char;
B: string[5];
end;

procedure TForm1.Button8Click(Sender: TObject);
begin
ShowMessage(IntToStr(SizeOf(T)));
end;

答案是8,即2+1+5

时间: 2024-10-14 16:38:14

String[255]在高版本Delphi里还是被解释成Byte,总体长度256,使用StrPCopy可以给Array String拷贝字符串的相关文章

高版本自动接听电话方法

原文地址:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=894679&page=1&_dsign=b92c470b 高版本自动接听电话方法:             try {                 Method method = Class.forName("android.os.ServiceManager")                         .getMethod(&q

html5调用本机摄像头兼容谷歌浏览器高版本,谷歌浏览器低版本,火狐浏览器

做这个功能的时候在网上查了一些资料,代码如下,在这个代码在谷歌浏览器46版本是没问题的,在火狐浏览器也行,但是在谷歌浏览器高版本下是不兼容的 <div id="body"> <section class="featured"> <div class="content-wrapper"> <hgroup class="title"> <h1>Welcome to web

低版本中使用高版本出现的类怎么办?

原理概述 简单来说就是三个字——黑魔法. 利用这种黑魔法的例子已经越来越多,我所知道的最早使用这种方法的是一个老外在三年为了解决NSUUID而使用的. 我们国内团队开发的FDStackView是一个非常好的开源库,已经有1500+颗星星了,希望大家多多支持我们国内的团队,在FDStackView库中也用到了相同的技术,网上有人发出了分析实现原理的文章,但分析的很浅,而且根本没有说在点子上,使得这种黑魔法的魅力并没有被大家欣赏到,我这里做了一些功课,把这个原理详细的阐述一下,以及这里的关键点在哪里

错误: -source 1.6 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符)

今天晚上在AS上运行校长项目时,报错如下: Error:(71, 35) 错误: -source 1.6 中不支持 diamond 运算符(请使用 -source 7 或更高版本以启用 diamond 运算符) 这个错误对应程序里的代码是: 一般正确的写法是在声明的时候指定类型,也就是: List<PublicBlogListBean>  _hotDatas = new ArrayList<PublicBlogListBean>(); 但是在JDK 1.7里新增了一个新特性: 增强

JDK几个高版本的新特性

JDK 高版本的新特性 1.JDK5的新特性: 自动拆装箱 见Integer部分笔记 泛型 增强for循环 静态导入 可变参数 见集合部分笔记 枚举 是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内.举例:一周只有7天,一年只有12个月等. 回想单例设计模式:单例类是一个类只有一个实例 那么多例类就是一个类有多个实例,但不是无限个数的实例,而是有限个数的实例.这才能是枚举类. 我们自己定义枚举类比较麻烦,所以,java就提供了枚举类供我们使用. 格式是:只有枚举项的枚举类 publi

高版本Android如何利用反射调用系统隐藏的远程服务拦截来电

要说拦截Android系统来电,就不得不说起在低版本的时候Android提供给开发者使用的一个方法:endCall(),但由于谷歌后来考虑到对于一部手机来说,最重要的功能就是打电话了,如果这个功能随随便便就被人屏蔽了,安全性太差,所以在高版本的Android将这个方法屏蔽了,不再在TelephoneManager中暴露这个方法. 那么我们下面的目标就是要想办法调用到这个方法,当然首先我们还是需要实现一个广播接收者,来接收电话状态改变的广播,这里使用在服务中动态注册广播接收者的方法来实现,主要好处

Oracle SQL 语句高版本分析

OracleSQL 语句高版本分析 1.     何为高版本 每次执行一条SQL语句时,如果其对应的当前已经存在于library cache里的一个父游标下的各个子游标都不能被该SQL语句重新使用(即共享),则会产生一个新的子游标,此时就会在V$SQL_SHARED_CURSOR里新增一行,分别描述该SQL语句不能使用当前已经存在的各个子游标的原因.当然一个父游标下的第一个子游标产生时也会在该视图上新增一行,只是各个该视图上的描述原因的列的值都为N,在V$SQL_SHARED_CURSOR行数就

Android 开源项目android-open-project工具库解析之(二) 高版本向低版本兼容,多媒体相关,事件总线(订阅者模式),传感器,安全,插件化,文件

六.Android 高版本向低版本兼容 ActionBarSherlock 为Android所有版本提供统一的ActionBar,解决4.0以下ActionBar的适配问题 项目地址:https://github.com/JakeWharton/ActionBarSherlock Demo地址:https://play.google.com/store/apps/details?id=com.actionbarsherlock.sample.demos APP示例:太多了..现在连google都

解决Safari高版本浏览器中默认禁用第三方COOKIE(含demo)

前段时间在项目里遇到了一个比较头疼的问题,就是高版本的Safari中默认会阻止第三方cookie,这使得使用Safari浏览器的用户无法按照正常的业务逻辑进行操作. 问题展现 知识点 什么是第三方cookie呢?在访问一个网站A时,网站A算作第一方,如果网站A中引用了另一个网站B(网站B的域名与网站A的域名不同)的资源,这时这个网站B就被认为是第三方.需要注意的是,这儿区分不同网站的标准是域名是否相同,而不是这两个网站是否由同一个公司运营.比如,taobao.com和tmall.com被认为是两