views:

648

answers:

5

Is there a way to get strings in records bigger than 255 chars?

EDIT:

I have something like the following:

TQuery = Record
  Action: string[255];
  Data: string;
end;

if I now say:

Test: TQuery;
Test.Data := 'ABCDEFGHIJKLMN...up to 255...AISDJIOAS'; //Shall be 255 chars

It does not work and the compiler complains... How to fix that?

+4  A: 

Normally yes. You don't have to do something special as long as you use the normal String type (or the other long string types) and not ShortString.

type
  TMyRec = record
    Value: string;
  end;

In practice it depends what do you want to do with the record. If you want to block-write something into a file or provide the record to a DLL function, you have to switch to char arrays:

type
  TMyRec = record
    Value: array[0..1023] of Char;
  end;
DR
I think this will be problematic when something like "file of record" comes into play.
Uwe Raabe
Thanks for the hint. I updated my answer.
DR
A: 

If you mean, storing it into a database then it's completely dependent on the database you are using. Several databases support strings up to 8K in length; and SQL 2005 introduced varchar(MAX) which has a limit of, i believe 2GB. MySql 5 seems to be limited to about 65K for that same datatype.

However, some of the older ones only allow [var]char(255).

What are you trying to put it in?

Chris Lively
i say: "select * from Orders" and get back a huge string.
Acron
Then it sounds like your DB supports it. Can you define the problem you have a little further? For example, are you receiving an error message when trying to update that record?
Chris Lively
A: 

In Delphi there are different types of string:

  • ShortString - up to 255 Chars
  • AnsiString - up to 2^31 Chars
  • WideString - up to 2^31 WideChars

string is normally interpreted as AnsiString. AnsiString & WideStrings are actually pointer to memory where the string is stored. The compiler does some magic there to save resources.

So putting a string into a record can give you the desired result but I guess the sizeof operator on the record will fail.


Thx to Smasher for pointing this out: This is cited from Delphi 2006 help. Different Delphi Versions may behave different.

Tobias Langner
SizeOf counts the length of the pointer. You need the Length function to get the length of a string.
Gamecat
"string is normally interpreted as AnsiString" - This is not true for Delphi 2009, where String is interpreted as a unicode string.
Smasher
+4  A: 

Delphi and the three strings

Once upon a time, in the early days of pascal, there where short strings. They consisted of a block of bytes with a max size of 256. The first byte was the length byte:

5, H, e, l, l, o

You could define fixed length strings to save memory:

a: string[5];

Windows uses C strings, which are a pointer to a memory block terminated with a 0 character. These strings where not limited to 255 bytes. First they where provided as the PChar (pointer to char). But later the default string was interpreted as a C type string. You still could use shortstrings:

a: string[22];
b: ShortString;
c: string; // C (Delphi) string

With Delphi 2009, Unicode was introduced. Now each string was a Unicode string. Which is a pointer to a piece of memory containing unicode characters. We still have the ShortString type. The old ansi strings could be accessed by AnsiString or PAnsiChar.

Now that strings are pointers, there is no limit to the size. But string literals are still limited to 255 characters.

Gamecat
nice story! did you notice the OP specifically asked about "records"? You did not use that word! :-)
Argalatyr
+5  A: 

If you want to be able to write your record to a file, you can define your string as an array of ansichar for example. You can treat it like a string afterwards.

Example:

program StrInRecTest;
{$APPTYPE CONSOLE}
uses SysUtils;

type
  TStringRec=
    packed record
        S:array[0..1023] of ansichar;
    end;

var
  StringRec:TStringRec;
  F:File of TStringRec;
begin
  StringRec.S := 'Hello';
  WriteLn(StringRec.S);
  WriteLn('First char is:'+StringRec.S[0]); // watch out with this


  // now let's try saving this to a file and reading it back...

  // make a long string with x-es
  FillChar(StringRec.S,Length(StringRec.S),'X');
  StringRec.S[High(StringRec.S)] := #0; // terminate the string

  WriteLn(StringRec.S);

  // write to a file
  AssignFile(F,'tmp.txt');
  ReWrite(F);
  Write(F,StringRec);
  CloseFile(F);

  WriteLn;

  // read from file
  AssignFile(F,'tmp.txt');
  Reset(F);
  Read(F,StringRec);
  CloseFile(F);

  WriteLn(StringRec.S); // yay, we've got our long string back

  ReadLn;
end.
Wouter van Nifterick
updated my question.
Acron