Reference blog: http://www.cnblogs.com/pchmonster/archive/2011/12/14/2287686.html
Wherein all of the code are at Delphi7 test.
In Delphi 4,5,6,7 character string types include:
-
Short string (Short String)
-
Long strings (Long String)
-
Wide string (Wide String)
-
Zero-terminated string (Null-Terminated String), PChar and array of characters
1, short string (Short String)
Fixed length, the maximum number of characters is 255, also referred to a short string length bytes (Length-byte) string, because the 0-th element contains the short length of the string (string string the number of characters). Thus ShortString default maximum length is 256 bytes (255 characters in length byte + 1 = 256), a short string declared in two ways, as follows:
1
2
3
4
5
6
7
8
9
|
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函数可以把一个字符类型转换为整数类型}
Len := SizeOf(S);
{ Len现在包含的是ShortString类型的大小,为256字节,并不是字符串的长度}
end
;
|
Examples of the above [0] of the length of the string S can be obtained, of course, also be used to determine the length of the Length function by a short string S.
Characters can access a particular location in ShortString by the array index, the following examples with reference to the specific use, and notes:
1
2
3
4
5
6
7
8
9
10
11
12
|
var
S:
string
[
8
];
{这种定义方式,是定义S是一个字符串,且S是最多含有8个字符的字符串}
i:
Integer
;
begin
S :=
'a_pretty_darn_long_string'
;
{ 因为S只有8个字符大小,
因此s的实际存储的内容为“a_pretty”}
i :=
10
;
S[i] :=
's'
;
{ 因为S只有8个字符大小,
试图改写第10个元素,将会使内存混乱}
end
;
|
2, long strings (Long String)
Long string (the AnsiString) is assigned a dynamic string, the size of which is limited only by available memory. Declare a long string, just use the keyword String does not increase the small parameter can be.
Delphi 7 AnsiString characters contained in a single byte is stored.
1
2
|
var
S:
string
;
|
Because it is dynamically allocated, once free to modify the string, without worrying about the impact on the other, do not worry about cross-border issues. String element type is not 0, attempts to access the elements of type String 0 will produce a compilation error.
Length function can be obtained by the length of the string, the process can also SetLength long string length disposed. Partitioned in memory as follows:
Note that when given a String type assignment when Fu string is too long, may be error: "String literals may have at most 255 elements". This time you wonder: is not to say there is no limit the number of characters String of it?
For this problem, we give a code sample ( program 1 )
1
2
3
4
5
6
|
var
s:
string
;
begin
s:=
'<?xml version="1.0" encoding="UTF-8"?><Msg><AppHdr><CharSet>UTF-8</CharSet><Fr>000100</Fr><To>SDC</To><BizMsgIdr>0000000002</BizMsgIdr><MsgDefIdr>V1.0</MsgDefIdr><BizSvc>067</BizSvc><CreDt>20130227100434</CreDt><Sgntr>fb3LY5VmhonZwhP+ntxI9A==</Sgntr></AppHdr><Document><Data><FndNm>name</FndNm><TtlFndVol>12681656.00</TtlFndVol><FndCd>159999</FndCd><FndSts>0</FndSts><NAV>1.0251</NAV><NtValDt>20130301</NtValDt><NtValTp>0</NtValTp></Data></Document></Msg>'
;
end
.
|
This time, a length greater than the string 255 is directly assigned to a variable of type string above mentioned error will be reported. The alternative is to be a long string into multiple parts, when used in an assignment + by assignment, see example ( Procedure 2 )
1
2
3
4
5
6
7
8
9
10
|
var
s:
string
;
begin
s:=
'<?xml version="1.0" encoding="UTF-8"?><Msg><AppHdr><CharSet>UTF-8</CharSet><Fr>000100</Fr><To>SDC</To>'
+
'<BizMsgIdr>0000000002</BizMsgIdr><MsgDefIdr>V1.0</MsgDefIdr><BizSvc>067</BizSvc><CreDt>20130227100434</CreDt>'
+
'<Sgntr>fb3LY5VmhonZwhP+ntxI9A==</Sgntr></AppHdr><Document><Data><FndNm>FundName</FndNm><TtlFndVol>12681656.00</TtlFndVol>'
+
'<FndCd>159999</FndCd><FndSts>0</FndSts><NAV>1.0251</NAV><NtValDt>20130301</NtValDt><NtValTp>0</NtValTp></Data>'
+
'</Document></Msg>'
;
end
.
|
This time it can compile a success
3, wide string (Wide String)
Wide and long string as a string, restricted only by the size of available memory, and the implementation of dynamic allocation.
在Delphi 7 中WideString被实现为2个字节存储一个字符,用WideString来处理多字节字符(比如汉字)是十分方便的。如:
1
2
3
4
5
6
7
8
9
10
|
var
S:
string
;
{ 在Delphi 7中默认string等同于AnsiString}
WS:
WideString
;
begin
S :=
'世界你好'
;
WS := S;
ShowMessage(S[
1
]);
{ 此时无任何显示,因为S[1]取出的是‘世’的一半}
ShowMessage(WS[
1
]);
{ 显示‘世’}
end
;
|
要理解宽字符串就必须理解字符编码的规则,比如ASCII、UTF-8……
4、零结尾字符串(Null-Terminated String)、PChar和字符数组
在C和C++中没有真正的字符串数据类型,都是通过以Null结尾(0)的字符数组来实现的,字符数组没有长度字节,因此只能通过结尾的Null标志来作为字符串的字符结束标志。又因为Windows是用C编写的,很多Windows函数要用到以字符数组作为参数,但Pascal字符串类型不是字符数组,因为为了让Pascal字符串也能与Windows兼容,就需要一个字符串数组,PChar类型正是符合这种需求,在任何需要字符数组的地方都可用PChar。
虽然AnsiString和WideString都已经实现了NULL
相应的也有PAnsiChar和PWideChar,分别对应于AnsiChar字符和WideChar字符。
例如:Windows MessageBox函数,此函数声明如下:
1
|
function
MessageBox(hWnd: HWND; lpText, lpCaption:
PChar
; uType: UINT):
Integer
; stdcall;
|
第二个和第三个参数需要一个指向字符数组的指针,为了可以调用此函数,有以下三种方法来实现
1、PChar()类型转换
1
2
3
4
5
6
7
8
9
|
var
Text:
string
;
Caption:
string
;
begin
Text :=
'This is a test.'
;
Caption :=
'Test Message'
;
MessageBox(
0
,
PChar
(Text),
PChar
(Caption),
0
);
{ 这里PChar用来把string类型转换为Null结尾的字符串}
end
;
|
其中
2、PChar变量
我们先做一个实现,看看PChar类型到底是啥呢?
运行下面程序:
1
2
3
4
5
6
7
8
9
|
var
Text:
PChar
;
{ 声明为PChar类型}
Str:
string
;
{ 声明为String类型}
begin
Text :=
'This is a test.'
;
{ 都被赋予了相同的字符串}
Str :=
'This is a test.'
;
ShowMessage(IntToStr(SizeOf(Text)));
{ 4字节,实质是指针}
ShowMessage(IntToStr(SizeOf(Str)));
{ 也是4字节,也是指针}
end
;
|
通过上面的程序,我们知道Text(PChar类型)只不过是一个指针而已。
1
2
3
4
5
6
7
|
var
Text:
PChar
;
begin
Text :=
'This is a test.'
;
MessageBox(
0
, Text,
'Test Message'
,
0
);
{ 这里Text直接声明为了PChar类型,字符串常量可以直接用}
end
;
|
Text pointer points to a memory area of such a contained end Null 'This is a test.' Character string region. Which is equivalent to the following code:
1
2
3
4
5
6
7
8
9
10
|
const
TempString:
array
[
0..15
]
of
Char
=
'This is a test.'
#
0
;
var
Text:
PChar
;
begin
Text := @TempString[
0
];
{Text指向Null结尾的TempString字符数组的第0个元素的地址,
也就是整个字符数组的首地址}
MessageBox(
0
, Text,
'Test Message'
,
0
);
end
;
|
3, Char type array of characters
Last Char array can also be used instead of PChar, code is as follows:
Appearances in careful cross-border access memory
1
2
3
4
5
6
7
8
9
10
11
12
|
var
Text1:
array
[
0..14
]
of
Char
;
{ 大小为15个字符}
Text2:
array
[
0..20
]
of
Char
;
{ 大小为21个字符}
begin
Text1 :=
'This is a test.'
;
{Text1和Text2的字符长度都为15个字符}
Text2 :=
'This is a test.'
;
MessageBox(
0
, Text1,
'Test Message 1'
,
0
);
{因为Text1的字符长度超过了其声明的大小,因为会内存访问混乱,显示换乱}
MessageBox(
0
, Text2,
'Test Message 2'
,
0
);
{Text2的字符长度比起声明的大小要小,因为正常访问,显示正确}
end
;
|
The results show the following:
On the string on the first shallow we talked about this at a later time understanding.