pascal语言中字符串操作

合集下载

PASCAL中常用的函数和过程

PASCAL中常用的函数和过程
4、四舍五入函数 round(x) 定义:function Round(X: Real): Longint; 注意:X 是实型表达式. Round 返回 Longint 型的 X 的四舍五入值.如果返回值 超出了 Longint 的表示范围,则出错. 例子: begin Writeln(1.4, ' rounds to ', Round(1.4)); { 1 } Writeln(1.5, ' rounds to ', Round(1.5)); { 2 } Writeln(-1.4, 'rounds to ', Round(-1.4));{ -1 }
随机数在信息学奥林匹克中可用于随机化搜索、穷举等算法,以优化其性能, 也可用于在快速排序中选择关键数,以使其快速排序算法的最坏情况没有固定的 相应数列。
另外,System 单元中随机种子变量的标识符为 RandSeed,你也可以手动修 改它。如果你希望使用了随机数的程序对同一个输入数据能有恒定的输出结果, 可以设置 RandSeed 为一个定值。
附: 如何获取随机数?
随机数是指理论上没有规律可循、在指定范围内每个数的出现几率相等、无 法根据之前的数来预测下一个数的数列。一般随机数生成器的基本原理是:首先 初始化一个随机种子,其初始值可以是任意的整数;在每次获取随机数时,以随 机种子为基础进行某种特殊的运算,获得一个随机数并返回之,然后再对随机种 子进行某种运算,改变随机种子的值。这样,就可以生成许多比较随机的数,但 同一个初始值的随机种子将会生成完全相同的随机数列。
Writeln(-1.5, 'rounds to ', Round(-1.5));{ -2 } end.
5、取小数函数 frac(x) 定义:function Frac(X: Real): Real; 注意:X 是实型表达式. 结果返回 X 的小数部分; 也就是说, Frac(X) = X - Int(_X). 例子: var R: Real; begin R := Frac(123.456); { 0.456 } R := Frac(-123.456); { -0.456 } end.

Delphi(pascal)的函数手册_编程必备

Delphi(pascal)的函数手册_编程必备

delphi(pascal)的函数手册名称类型说明---------------------------------------------------------------------------------- Abort 函数引起放弃的意外处理Abs 函数绝对值函数AddExitProc 函数将一过程添加到运行时库的结束过程表中Addr 函数返回指定对象的地址AdjustLineBreaks 函数将给定字符串的行分隔符调整为CR/LF序列Align 属性使控件位于窗口某部分Alignment 属性控件标签的文字位置AllocMem 函数在堆栈上分配给定大小的块AllowGrayed 属性允许一个灰度选择AnsiCompareStr 函数比较字符串(区分大小写)AnsiCompareText 函数比较字符串(不区分大小写)AnsiLowerCase 函数将字符转换为小写AnsiUpperCase 函数将字符转换为大写Append 函数以附加的方式打开已有的文件ArcTan 函数余切函数AssignFile 函数给文件变量赋一外部文件名Assigned 函数测试函数或过程变量是否为空AutoSize 属性自动控制标签的大小BackgroundColor 属性背景色BeginThread 函数以适当的方式建立用于内存管理的线程BevelInner 属性控件方框的内框方式BevelOuter 属性控件方框的外框方式BevelWidth 属性控件方框的外框宽度BlockRead 函数读一个或多个记录到变量中BlockWrite 函数从变量中写一个或多个记录BorderStyle 属性边界类型BorderWidth 属性边界宽度Break 命令终止for、while、repeat循环语句Brush 属性画刷Caption 属性标签文字的内容ChangeFileExt 函数改变文件的后缀ChDir 函数改变当前目录Checked 属性确定复选框选中状态Chr 函数返回指定序数的字符CloseFile 命令关闭打开的文件Color 属性标签的颜色Columns 属性显示的列数CompareStr 函数比较字符串(区分大小写)Concat 函数合并字符串Continue 命令继续for、while、repeat的下一个循环Copy 函数返回一字符串的子串Cos 函数余弦函数Ctl3D 属性是否具有3D效果Cursor 属性鼠标指针移入后的形状Date 函数返回当前的日期DateTimeToFileDate 函数将DELPHI的日期格式转换为DOS的日期格式DateTimeToStr 函数将日期时间格式转换为字符串DateTimeToString 函数将日期时间格式转换为字符串DateToStr 函数将日期格式转换为字符串DayOfWeek 函数返回星期的数值Dec 函数递减变量值DecodeDate 函数将日期格式分解为年月日DecodeTime 函数将时间格式分解为时、分、秒、毫秒Delete 函数从字符串中删除子串DeleteFile 命令删除文件DiskFree 函数返回剩余磁盘空间的大小DiskSize 函数返回指定磁盘的容量Dispose 函数释放动态变量所占的空间DisposeStr 函数释放字符串在堆栈中的内存空间DitherBackground 属性使背景色的色彩加重或减少50%DragCursor 属性当鼠标按下时光标的形状DragMode 属性按动的作用方式DropDownCount 属性容许的显示数据项的数目EditMask 属性编辑模式Enabled 属性是否使标签呈现打开状态EncodeDate 函数将年月日合成为日期格式EncodeTime 函数将时、分、秒、毫秒合成为时间格式EndMargin 属性末尾边缘Eof 函数对有类型或无类型文件测试是否到文件尾Eoln 函数返回文本文件的行结束状态Erase 命令删除外部文件ExceptAddr 函数返回引起当前意外的地址Exclude 函数从集合中删除一些元素ExceptObject 函数返回当前意外的索引Exit 命令立即从当前的语句块中退出Exp 函数指数函数ExpandFileName 函数返回包含绝对路径的字符串ExtendedSelect 属性是否允许存在选择模式,True时,MultiSelect才有意义ExtractFileDir 函数返回驱动器和路径ExtractFileExt 函数返回文件的后缀ExtractFileName 函数返回文件名ExtractFilePath 函数返回指定文件的路径FileAge 函数返回文件已存在的时间FileClose 命令关闭指定的文件FileCreate 命令用指定的文件名建立新文件FileDateToDateTime 函数将DOS的日期格式转换为DELPHI的日期格式FileExists 函数检查文件是否存在FileGatAttr 函数返回文件的属性FileGetDate 函数返回文件的DOS日期时间标记FileOpen 命令用指定的存取模式打开指定的文件FilePos 函数返回文件的当前指针位置FileRead 命令从指定的文件读取FileSearch 命令在目录中搜索指定的文件FileSeek 函数改变文件的指针FileSetAttr 函数设置文件属性FileSetDate 函数设置文件的DOS日期时间标记FileSize 函数返回当前文件的大小FileWrite 函数对指定的文件做写操作FillChar 函数用指定的值填充连续字节的数{e.gGetMem(R, SizeOf(TMyRecord));FillChar(R^, SizeOf(TMyRecord), #0);SetLength(R.S, $FFFF);FreeMem(R); // 不会释放R.S 内存空间!!}FindClose 命令终止FindFirst/FindNext序列FindFirst 命令对指定的文件名及属性搜索目录FindNext 命令返回与文件名及属性匹配的下一入口FloatToDecimal 函数将浮点数转换为十进制数FloatToStrF 函数将浮点数转换为字符串FloatToStr 函数将浮点数转换为字符串FloatToText 函数将给定的浮点数转换为十进制数FloatToTextFmt 函数将给定的浮点数转换为十进制数Flush 函数将缓冲区的内容刷新到输出的文本文件中FmtLoadStr 函数从程序的资源字符串表中装载字符串FmtStr 函数格式化一系列的参数,其结果以参数Result返回Font 属性设置字体Format 函数格式化一系列的参数并返回Pascal字符串FormatBuf 函数格式化一系列的参数FormatDateTime 函数用指定的格式来格式化日期和时间FormatFloat 函数指定浮点数格式Frac 函数返回参数的小数部分FreeMem 函数按给定大小释放动态变量所占的空间GetDir 返回指定驱动器的当前目录GetHeapStatus 返回内存管理器的当前状态GetMem (var P: Pointer; Size: Integer);{(建立一指定大小的动态变量)分配一个指定大小的内存块(连续),并将指针指向该处}GetMemoryManager 返回内存管理器的入口点Glyph 函数按钮上的图象学习视频网:Halt 停止程序的执行并返回到操作系统Hi 返回参数的高地址位High 返回参数的上限值Hint 属性提示信息Int 返回参数的整数部分Include 添加元素到集合中Insert 在字符串中插入子串IntToHex(,) 将整型数转换为十六进制数。

Pascal中的常用字符串函数

Pascal中的常用字符串函数

1. 连接运算conca‎t(s1,s2,s3…sn) 相当于s1‎+s2+s3+…+sn.例:conca‎t(‘11’,’aa’)=’11aa’;2. 求子串。

Copy(s,I,L) 从字符串s‎中截取第I‎个字符开始‎后的长度为‎l的子串。

例:copy(‘abdag‎’,2,3)=’bda’3. 删除子串。

过程Delet‎e(s,I,l) 从字符串s‎中删除第I‎个字符开始‎后的长度为‎l的子串。

例:s:=’abcde‎’;delet‎e(s,2,3);结果s:=’ae’4. 插入子串。

过程Ins‎e rt(s1,s2,I) 把s1插入‎到s2的第‎I个位置例:s:=abc;inser‎t(‘12’,s,2);结果s:=’a12bc‎’5. 求字符串长‎度lengt‎h(s) 例:lengt‎h(‘12abc‎’)=56. 搜索子串的‎位置pos(s1,s2) 如果s1是‎s2的子串‎,则返回s1‎的第一个字‎符在s2中‎的位置,若不是子串‎,则返回0.例:pos(‘ab’,’12abc‎d’)=37. 字符的大写‎转换。

Upcas‎e(ch) 求字符ch‎的大写体。

例:upcas‎e(‘a’)=’A’8. 数值转换为‎数串。

过程Str(x,s) 把数值x化‎为数串s.例:str(12345‎,s); 结果s=’12345‎’9. 数串转换为‎数值。

过程val‎(s,x,I) 把数串s转‎化为数值x‎,如果成功则‎i=0,不成功则I‎为无效字符‎的序数例:val(‘1234’,x,I);结果x:=1234求长度le‎n gth定义:funct‎i on Lengt‎h(S: Strin‎g): Integ‎e r;例子:varS: Strin‎g;begin‎Readl‎n (S);Write‎l n('"', S, '"');Write‎l n('lengt‎h = ', Lengt‎h(S));end.复制子串c‎o py定义:funct‎i on Copy(S: Strin‎g; Index‎:Integ‎e r; Count‎:Integ‎e r): Strin‎g;注意:S 是字符串类‎型的表达式‎。

PASCAL语言简介

PASCAL语言简介

第一个程序Pascal语言的编译器有很多,我们这里以Dev-Pascal为主要编程工具。

该软件界面如下:我们输入如下代码后编译运行。

1 2 3 4 5 program my_program; {程序首部,程序名或简单说明} begin {程序开始的标志}write('Hello,World'); {屏幕上输出单引号下的内容}readln; {等待操作者按一次回车}end. {程序结束的标志}如果没有输入错误的话,计算机应能在黑色背景上显示“Hello,World”。

例:计算a+b的值。

1 2 3 4 5 program circle;vara,b,x:integer;{定义变量} begina:=100;1.点击New source file按钮新建一源文件2.输入代码并保存,保存路径不得有中文字符3.编译并运行6 7 8 9 10 b:=50;x:=a+b;writeln('a+b=',x);{输出并换行} readln;end.Pascal字符与符号1.标识符(1) 标识符的定义:标识符就是以字母开头的字母数字序列,有效长度为63个字符,并且大小写等效。

可以用来标示常量、变量、程序、函数等。

(2) 标识符的分类:a.保留字(关键字)所谓保留字是指在Pascal语言中具有特定的含义,你必须了解它的含义,以便于正确的使用,否则会造成错误。

下面是Pascal语言的保留字:AND ARRAY BEGIN CASE CONST DIV DO DOWNTOELSE END FILE FOR FUNTION GOTO IF INLABEL MOD NIL NOT OF OR PACKED PROCEDUREPROGRAM RECORD REPEAT SET THEN TO TYPEUNTIL VAR WHILE WITHb.标准标识符:指Pascal语言预先定义的标识符,具有特殊含义。

pascal常用函数(较全)

pascal常用函数(较全)

pascal函数PASCAL内自带的函数,通常可以直接调用,特殊的需要调用数据库,如:used math 目录一、数学函数与过程二、字符串函数与过程三、标准函数四、各单元的函数与过程展开一、数学函数与过程过程:inc(i) 使i:=i+1;inc(i,b) 使i:=i+b;dec(i) 使i:=i-1;dec(i,b) 使i:=i-b;randomize 随机数的种子函数,在每次设置随机数时都要把这个函数放在最前面。

函数:abs(x) 求x的绝对值。

例:abs(-3)=3 x为整数chr(x) 求编号x对应的字符。

例:chr(65)='A' chr(97)='a'chr(48)='0' x为非负整数ord(x) 求字符x对应的编号。

例:ord(‘A')=65 ord(‘a')=97 另外:ord(false)=0 ord(true)=1 x为字符或数字或布尔量sqr(x) 求x的平方。

例:sqr(4)=16 x为整数sqrt(x) 求x的正根。

例:sqrt(16)=4 (ps:负数是不能进行运算的,如果需要就要先取绝对值:sqrt(-4)是错的,应该为sqrt(abs(-4))结果为实数round(x) 求x的四舍五入。

例:round(4.5)=5 x实数trunc(x) 求x的整数部分。

例:trunc(5.6)=5 结果是integer型 x 为实数int(x) 求x的整数部分。

例:int(5.6)=5.0 结果是real型 x为实数frac (x) 求x的小数部分。

例:frac(5.6)=0.6 x为实数pred(x) 求x的前导。

例:pred(‘b')='a' pred(5)=4pred(true)=false x为字符或数字或布尔量succ(x) 求x的后继。

例:succ(‘b')='c' succ(5)=6succ(false)=true x为字符或数字或布尔量odd(x) 判断x是否为奇数。

PASCAL程序基础

PASCAL程序基础

2.输入语句(read,readln): 格式:read(变量名表); readln<(变量名表)> read(a1,a2,a3); 等价于 read(a1);read(a2);read(a3); readln(a1,a2,a3); 等价于 read(a1);read(a2);read(a3);readln; 功能:通过键盘,给指定的变量赋值。 【例3】:写出程序运行后,变量的值。 程序代码: program ex3; var a,b,c:integer; i,j,k:real; ch1,ch2,ch3:char; 执行readln后多余的数据将被忽 begin read(a,b,c); 略;执行read后多余的数据要么 readln(i,j,k); 被忽略,要么被下一个read或 read(ch1,ch2,ch3); readln语句所读入。 writeln(„a=‟,a,„b=‟,b,„c=‟,c); writeln(„i=‟,i, „j=‟,j,„k=‟,k); writeln(„ch1=‟,ch1,„ch2=‟,ch2,„ch3=‟,ch3); end. 程序运行后,输入数据: 12345 6.1 7 8 9 0 dos
A——Z;a——z;0——9;+,-,*,/,=,<>,<=,
>=,<,>,(,),[,], {,},:=,,,;,.,:,..,',^ 注:Pasca语言除了能使用以上规定的基本符号外,不 得使用任何其它符号。
三、PASCAL数据类型
数据的一个重要特征就是它的类型,数据类型
确定了数据的构成和可进行的运算。Pascal语
四、常量与变量
2.变量 (1)变量:在某个程序的运行过程中其值可以发生改变的量 (2)变量说明:变量说明出现在说明部分。语法格式: var var 变量标识符列表:类型; a,b,c:integer; ... m,n:real ; 变量标识符列表:类型;

pascal语法讲义-第七讲

pascal语法讲义-第七讲

第七讲 数组与字符串一、一维静态数组我们先来思考一个问题。

例题1.4.2.1.1:读入3个数,将之倒序输出。

想必这个程序对大家来说没有难度。

program p1_4_2_1_1(input,output);var a,b,c:longint;beginreadln(a,b,c);writeln(c,' ',b,' ',a);readln();end.下面我们来思考一个升级版的问题:例题1.4.2.1.2:读入1000个数,将之倒序输出。

这个程序对于大家来说肯定也是可以搞定的,只不过相对而言比较麻烦,这里我们提供一个生成该程序源文件的程序。

program p1_4_2_1_2_producer(input,output);var i:longint;beginassign(output,'p1_4_2_1_2.pas');rewrite(output);writeln('program p1_4_2_1_2(input,output);');write('var ');for i:=1 to 999 do write('a',i,',');writeln('a1000:longint;');writeln('begin');write('readln(');for i:=1 to 999 do write('a',i,',');writeln('a1000);');write('writeln(');for i:=1000 downto 2 do write('a',i,',');writeln('a1);');writeln('readln();');writeln('end.');close(output);end.这里使用了一定文件的知识,如果把assign、rewrite、close 三行略去的话,大家应该可以看得懂。

PASCAL语言介绍(1)

PASCAL语言介绍(1)

4、程序完善题:共2题,每题14分,共 计28分。题目给出一段关于程序功能的 文字说明,然后给出一段程序代码,在 代码中略去了若干个语句或语句的一部 分并在这些位置给出空格,要求考生根 据程序的功能说明和代码的上下文,填 出被略去的语句。填对则得分;否则不 得分。
复赛 复赛的题型全部为上机编程题。题目包 括4道题,每题100分,共计400分。每一试 题包括:题目、问题描述、输入输出要求、 样例描述及相关说明。测试时,测试程序为 每道题提供了5-10组测试数据,考生程序每 答对一组得10-20分,累计分即为该道题的 得分。
程 序 设 计
基本 算法 处理
什么是计算机程序?
计算机程序(Computer Program,简称程序) 是语句的集合。语句是单词的集合。 为了编写一个机器语言程序,人类发明了汇编 语言。 汇编语言的词语是一些英文单词的缩略语和一 些数字。每条缩略语和一些数字的组合与机器 语言指令相对应。这样,人们就不用书写0和1 的机器语言代码了。写完程序后对照书本把英 文单词和数字翻译成0、1的代码就能完成机器 事实上,即使有了汇编语言( ASM语言),如果要它在屏幕上输 语言程序了。
Pascal语言简介
上埠镇中学 杜正瑞
全国青少年信息学奥林匹克联赛 (National Olympiad in Informatics in Provinces, 简称NOIP)
比赛中使用的程序设计语言是: PASCAL或C/C++ 10月份举行
初赛 初赛全部为笔试,满分100分。试题由四 部分组成: 1、选择题:共20题,每题1.5分,共计 30分。每题有5个备选答案,前10个题为 单选题(即每题有且只有一个正确答案, 选对得分),后10题为不定项选择题 (即每题有1至5个正确答案,只有全部 选对才得分)。普及组20个都是单选题。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

字符串类型在Borland公司的Turbo Pascal和16位Delphi中,传统的字符串类型是一个字符序列,序列的头部是一个长度字节,指示当前字符串的长度。

由于只用一个字节来表示字符串的长度,所以字符串不能超过255个字符。

这一长度限制为字符串操作带来不便,因为每个字符串必须定长(确省最大值为255),当然你也可以声明更短的字符串以节约存储空间。

字符串类型与数组类型相似。

实际上一个字符串差不多就是一个字符类型的数组,因为用[]符号,你就能访问字符串中的字符,这一事实充分说明了上述观点。

为克服传统Pascal 字符串的局限性,32位Delphi增加了对长字符串的支持。

这样共有三种字符串类型:∙ShortString 短字符串类型也就是前面所述的传统 Pascal 字符串类型。

这类字符串最多只能有255个字符,与16位Delphi中的字符串相同。

短字符串中的每个字符都属于ANSIChar 类型(标准字符类型)。

∙ANSIString长字符串类型就是新增的可变长字符串类型。

这类字符串的内存动态分配,引用计数,并使用了更新前拷贝(copy-on-write)技术。

这类字符串长度没有限制(可以存储多达20亿个字符!),其字符类型也是ANSIChar 类型。

∙WideString 长字符串类型与ANSIString 类型相似,只是它基于WideChar 字符类型,WideChar 字符为双字节Unicode 字符。

使用长字符串如果只简单地用String定义字符串,那么该字符串可能是短字符串也可能是ANSI长字符串,这取决于$H 编译指令的值,$H+(确省)代表长字符串(ANSIString 类型)。

长字符串是Delphi 库中控件使用的字符串。

Delphi 长字符串基于引用计数机制,通过引用计数追踪内存中引用同一字符串的字符串变量,当字符串不再使用时,也就是说引用计数为零时,释放内存。

如果你要增加字符串的长度,而该字符串邻近又没有空闲的内存,即在同一存储单元字符串已没有扩展的余地,这时字符串必须被完整地拷贝到另一个存储单元。

当这种情况发生时,Delphi运行时间支持程序会以完全透明的方式为字符串重新分配内存。

为了有效地分配所需的存储空间,你可以用SetLength 过程设定字符串的最大长度值:SetLength (String1, 200);SetLength 过程只是完成一个内存请求,并没有实际分配内存。

它只是把将来所需的内存预留出来,实际上并没有使用这段内存。

这一技术源于Windows 操作系统,现被Delphi用来动态分配内存。

例如,当你请求一个很大的数组时,系统会将数组内存预留出来,但并没有把内存分配给数组。

一般不需要设置字符串的长度,不过当需要把长字符串作为参数传递给API 函数时(经过类型转换后),你必须用SetLength 为该字符串预留内存空间,这一点我会在后面进行说明。

看一看内存中的字符串为了帮你更好地理解字符串的内存管理细节,我写了一个简例StrRef 。

在程序中我声明了两个全程字符串:Str1 和 Str2,当按下第一个按钮时,程序把一个字符串常量赋给第一个变量,然后把第一个变量赋给第二个:Str1 := 'Hello';Str2 := Str1;除了字符串操作外,程序还用下面的StringStatus 函数在一个列表框中显示字符串的内部状态:function StringStatus (const Str: string): string;beginResult := 'Address: ' + IntToStr (Integer (Str)) +', Length: ' + IntToStr (Length (Str)) +', References: ' + IntToStr (PInteger (Integer (Str) - 8)^) +', Value: ' + Str;end;在StringStatus 函数中,用常量参数传递字符串至关重要。

用拷贝方式(值参)传递会引起副作用,因为函数执行过程中会产生一个对字符串的额外引用;与此相反,通过引用(var)或常量(const)参数传递不会产生这种情况。

由于本例不希望字符串被修改,因此选用常量参数。

为获取字符串内存地址(有利于识别串的实际内容也有助于观察两个不同的串变量是否引用了同一内存区),我通过类型映射把字符串类型强行转换为整型。

字符串实际上是引用,也就是指针:字符串变量保存的是字符串的实际内存地址。

为了提取引用计数信息,我利用了一个鲜为人知的事实:即字符串长度和引用计数信息实际上保存在字符串中, 位于实际内容和字符串变量所指的内存位置之前,其负偏移量对字符串长度来说是-4(用Length 函数很容易得到这个值),对引用记数来说是-8。

不过必须记住,以上关于偏移量的内部信息在未来的Delphi版本中可能会变,没有写入正式Delphi文档的特性很难保证将来不变。

通过运行这个例子,你会看到两个串内容相同、内存位置相同、引用记数为2,如图7.1中列表框上部所示。

现在,如果你改变其中一个字符串的值,那么更新后字符串的内存地址将会改变。

这是copy-on-write技术的结果。

图 7.1: 例StrRef显示两个串的内部状态,包括当前引用计数第二个按钮(Change)的OnClick 事件代码如下,结果如图7.1列表框第二部分所示:procedure TFormStrRef.BtnChangeClick(Sender: TObject);beginStr1 [2] := 'a';ListBox1.Items.Add ('Str1 [2] := ''a''');ListBox1.Items.Add ('Str1 - ' + StringStatus (Str1));ListBox1.Items.Add ('Str2 - ' + StringStatus (Str2));end;注意,BtnChangeClick 只能在执行完BtnAssignClick 后才能执行。

为此,程序启动后第二个按钮不能用(按钮的Enabled 属性设成False);第一个方法结束后激活第二个按钮。

你可以自由地扩展这个例子,用StringStatus 函数探究其它情况下长字符串的特性。

Delphi 字符串与 Windows PChar字符串长字符串为零终止串,这意味着长字符串完全与Windows使用的C语言零终止串兼容,这给长字符串使用带来了便利。

一个零终止串是一个字符序列,该序列以一个零字节(或null)结尾。

零终止串在Delphi中可用下标从零开始的字符数组表示,C语言就是用这种数组类型定义字符串,因此零终止字符数组在Windows API 函数(基于C语言)中很常见。

由于Pascal长字符串与C语言的零终止字符串完全兼容,因此当需要把字符串传递给Windows API 函数时,你可以直接把长字符串映射为PChar 类型。

下例把一个窗体的标题拷贝给PChar 字符串(用API 函数GetWindowText),然后再把它拷贝给按钮的Caption 属性,代码如下:procedure TForm1.Button1Click (Sender: TObject);varS1: String;beginSetLength (S1, 100);GetWindowText (Handle, PChar (S1), Length (S1));Button1.Caption := S1;end;你可以在例LongStr 中找到这段代码。

注意:代码中用SetLength函数为字符串分配内存,假如内存分配失败,那么程序就会崩溃;如果你直接用PChar 类型传递值(而不是象以以上代码那样接受一个值),那么代码会很简单,因为不需要定义临时字符串,也不需要初始化串。

下面代码把一个Label(标签)控件的Caption 属性作为参数传递给了API函数,只需要简单地把属性值映射为PChar 类型:SetWindowText (Handle, PChar (Label1.Caption));当需要把WideString 映射为Windows兼容类型时,你必须用PWideChar 代替PChar进行转换,WideString常用于OLE和 COM 程序。

刚才展现了长字符串的优点,现在谈谈它的弊端。

当你把长字符串转换为PChar 类型时可能会引发一些问题,问题根本在于:转换以后字符串及其内容将由你来负责,Delphi 不再管了。

现在把上面Button1Click代码稍作修改:procedure TForm1.Button2Click(Sender: TObject);varS1: String;beginSetLength (S1, 100);GetWindowText (Handle, PChar (S1), Length (S1));S1 := S1 + ' is the title'; // this won't workButton1.Caption := S1;end;程序编译通过,但执行结果会令你惊讶,因为按钮的标题并没变,所加的常量字符串没有添加到按钮标题中。

问题原因是Windows写字符串时(在GetWindowText API调用中),Windows 没有正确设置Pascal 长字符串的长度。

Delphi 仍可以输出该字符串,并能通过零终止符判断字符串何时结束,但是如果你在零终止符后添加更多的字符,那么这些字符将被忽略。

怎么解决这个问题呢?解决方法是告诉系统把GetWindowText API函数返回的字符串再转换成Pascal字符串。

然而,如果你用以下代码:S1 := String (S1);Delphi 系统将不予理睬,因为把一种类型转换为它自己的类型是无用的操作。

为获得正确的Pascal 长字符串,需要你把字符串重新映射为一个PChar 字符串,然后让Delphi 再把它转回到字符串:S1 := String (PChar (S1));实际上,你可以跳过字符串转换(S1 := PChar (S1));,因为在Delphi中Pchar转换到string是自动执行的,最终代码如下:procedure TForm1.Button3Click(Sender: TObject);varS1: String;beginSetLength (S1, 100);GetWindowText (Handle, PChar (S1), Length (S1));S1 := String (PChar (S1));S1 := S1 + ' is the title';Button3.Caption := S1;end;另一个办法是用PChar 字符串的长度重新设定Delphi 字符串长度,可以这样写:SetLength (S1, StrLen (PChar (S1)));在例LongStr中你可以看到三种方法的结果,分别由三个按钮执行。

相关文档
最新文档