Delphi中的字符串字面量如何能够超过255个字符?

32

我正在使用Delphi 7,在处理字符串时发现了以下内容:

对于默认长度的字符串,即声明为 string 类型的字符串,其最大长度始终为 255。 ShortString 永远不允许增长到超过 255 个字符。

以上内容源自Delphi 字符串网站。

曾经我在 Delphi 代码中需要执行类似以下操作(针对一个非常大的查询):

  var
    sMyStringOF256characters : string;
    ilength : integer;
    begin
       sMyStringOF256characters:='ThisStringisofLength256,ThisStringisofLength256,.....'
       //length of sMyStringOF256characters is 256
    end;

我遇到了这个错误

[错误]u_home.pas(38): 字符串文字最多可以有255个元素。

但是当我尝试这样做时

    var
      iCounter              : integer;
      myExtremlyLongString  : string;
   begin
      myExtremlyLongString:='';
      Label1.Caption:='';
      for iCounter:=0 to 2500 do
         begin
            myExtremlyLongString:=myExtremlyLongString+inttostr(iCounter);
            Label1.Caption:=myExtremlyLongString;
         end;
         Label2.Caption:=inttostr(length(myExtremlyLongString));
   end; 

结果是:

enter image description here

正如您所见,myExtremlyLongString 的长度为 8894 个字符。

为什么 Delphi 没有报错,指出 myExtremlyLongString 的长度超过了 255 个字符?

编辑:我使用了

SetLength(sMyStringOF256characters,300);

但它没有起作用。


也许你只是看错了文档。顺便说一下,“动态分配”与......相比,你的意思真的不太清楚。 - OnTheFly
@user539484:意思是在运行时期间,在循环中可能会出现strVal:=mystring这样的情况,就像将循环值分配给字符串变量一样。 - PresleyDias
1
啊,那就删掉“动态”的说法吧,这里其实是在讨论赋值和声明的区别。你引用的内容是关于声明的,更具体地说,是关于编译器对字符字面量的限制。这种限制只是出于历史原因与Turbo Pascal字符串相关联。 - OnTheFly
1
我猜他们之所以不去除这个限制,只是因为没有实际理由需要字符串字面量超过70个字符... 对于编译器来说,这样的字面量在内部等同于array [0..N] of Char。希望现在更清楚了。 - OnTheFly
6个回答

46

为什么我的ExtremlyLongString没有超过255个字符的错误提示呢?

你可以在长字符串(AnsiString)一节中找到答案。

在Delphi的当前版本中,字符串类型只是AnsiString的别名,

因此,字符串不限于255个字符,但是字符串字面值是有限制的。这意味着您可以构建一个超过255个字符的字符串,但是您不能在代码中使用超过255个字符的字符串值。如果需要,您需要将它们拆分成多个字符串。

sMyString:='ThisStringisofLength255'+'ThisStringisofLength255';

3
你好,我来自2019年。非常抱歉告诉你这仍然是现实。但是谢谢你的回答! - ArieKanarie
2023年,依然如故。 - Mehmet Fide

12

将其拆分为:

sMyStringOF256characters := 
  'ThisStringis' +
  'ofLength256' +
  'And ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
  'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
  'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
  'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
  'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
  'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
  'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
  'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
  'CharactersCharactersCharactersCharactersCharactersCharactersCharactersCharacters';

1
+1,我曾经尝试过类似的东西(肯定小于255),用于查询一次,那时我认为限制是255,所以没有超过255..非常好的例子,谢谢。 - PresleyDias

5
在旧的DOS/Turbo Pascal时代,“字符串”确实被限制在255个字符以内。这在很大程度上是因为第一个字节包含了字符串的长度,而一个字节只能有0到255之间的值。
但在当代版本的Delphi中,这已经不再是问题了。
“ShortString”是旧的DOS/Pascal字符串类型。
“LongString”长时间以来一直是默认的字符串类型(包括我目前用于大部分生产工作的Borland Delphi 2006)。LongStrings(也称为“AnsiStrings”)保存8位字符,并且仅受可用内存的限制。
最近的Delphi版本(包括新的Delphi XE2)现在都默认使用多字节Unicode“WideString”字符串。像AnsiStrings一样,WideStrings在最大长度上也是“无限制”的。
本文对此进行了更详细的解释:

http://delphi.about.com/od/beginners/l/aa071800a.htm


2
这在当代版本的Delphi中已不再是问题,除了两个地方:字符串字面量和下标字符串(如string[50]),其中(显然!)限制为250或更少,在我提到的情况下,限制为50。 - Warren P
@Warren P - 你说得完全正确。对于字符串字面量的解决方法是使用其他线程中讨论的 "'mystring' + " 语法。 - paulsm4
这是错误的信息;大多数 Delphi 字符串类型的大小限制为2GB。 :-( http://docwiki.embarcadero.com/RADStudio/XE3/en/String_Types - alcalde

2

区别在于你的第一个代码示例中将字符串作为代码的一部分-字面字符串。这对它所允许的字符数有限制。

在第二个代码示例中,您是动态生成它而不是将其放置为一个大的文字字符串。

Delphi中的字符串类型(与shortstring不同,后者只能最多为255)可以达到您的内存大小。


+1,"可以达到你的内存大小。" 那是一个非常大的字符串。 - PresleyDias
2
它不能像你的内存那样大。最大的Delphi字符串类型仍然限于2GB的字符。http://docwiki.embarcadero.com/RADStudio/XE3/en/String_Types - alcalde

1
您可以尝试使用 StringBuilder 类:
procedure TestStringBuilder;
var
    I: Integer;
    StringBuilder: TStringBuilder;
begin
    StringBuilder := TStringBuilder.Create;
    try
        for I := 1 to 10 do
        begin
            StringBuilder.Append('a string ');
            StringBuilder.Append(66); //add an integer
            StringBuilder.Append(sLineBreak); //add new line
        end;

        OutputWriteLine('Final string builder length: ' + IntToStr(StringBuilder.Length));
    finally
        StringBuilder.Free;
    end;
end;

0
如果您需要在Delphi中使用非常长的字符串,可以从其他资源(如txt文件或带有任何扩展名的纯文本)中加载它。我正在使用它,它很有效。您可以使用纯文本行号创建“类似于”数组表。在Delphi代码中,您只能像@arjen van der Spek和其他人所说的那样操作。
对于我来说,使用格式化为var的文本文件-

sometext:string=
'txt...'+
'txt...'+
'txt...';

对于未来的编辑来说,这些标签是不好的。

优点:你可以使用任何长文本。

缺点:文本代码是开放的,任何人都可以在记事本等软件中打开文件并阅读它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接