Board index » delphi » Strings declared with constant length.

Strings declared with constant length.

//Example-----------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
  MyString : string[10];
  MyFile: TextFile;
begin
  MyString := 'Hello';
  AssignFile(MyFile, 'c:\Test.txt');
  Rewrite(MyFile);
  Writeln(MyFile, MyString);
  CloseFile(MyFile);

end;

//------------------------------------

In my file called Test.exe MyString has been concatenated.
To 'Hello'.

It should have been 'Hello     '.

There must be something that is wrong here or what??

Can some one tell me how to deal with this.

Sincerely Hans

 

Re:Strings declared with constant length.


string[10] does not specify a constant length of 10, it only specifies
a maximum length of 10.

On 19 Sep 1997 10:13:46 GMT, "Hans Petersson"

Quote
<hans.peters...@mbox302.swipnet.se> wrote:
>//Example-----------------------------
>procedure TForm1.Button1Click(Sender: TObject);
>var
>  MyString : string[10];
>  MyFile: TextFile;
>begin
>  MyString := 'Hello';
>  AssignFile(MyFile, 'c:\Test.txt');
>  Rewrite(MyFile);
>  Writeln(MyFile, MyString);
>  CloseFile(MyFile);

>end;

>//------------------------------------

>In my file called Test.exe MyString has been concatenated.
>To 'Hello'.

>It should have been 'Hello     '.

>There must be something that is wrong here or what??

>Can some one tell me how to deal with this.

>Sincerely Hans

_________________________________

Nick Roux
Johannesburg, South Africa
mailto:Nick.R...@Bigfoot.Com
_________________________________

Re:Strings declared with constant length.


Hi!

  In your code example, you are simply declaring the maximum length of the
string. Delphi does not fill the strings of predefined length with spaces!

This line:  MyString := 'Hello';
 only produces: 'Hello'

 To make Delphi write a formatted string to the text file use:
        MyString := Format('%-10s', ['Hello']);

 HTH!
 Regards,
 Bjorn
--
 __  __/  _/
    /    /__
   /       /
 _/   /___/

=======================================================================
           TransSoft Ltd - http://www.transsoft.com
"TransSoft's Mail Control - The Multiple Award Winning Email Client..."
=======================================================================

Hans Petersson <hans.peters...@mbox302.swipnet.se> wrote in article
<01bcc4e4$a373e3c0$a36ff482@hanspetersson>...

Quote
> //Example-----------------------------
> procedure TForm1.Button1Click(Sender: TObject);
> var
>   MyString : string[10];
>   MyFile: TextFile;
> begin
>   MyString := 'Hello';
>   AssignFile(MyFile, 'c:\Test.txt');
>   Rewrite(MyFile);
>   Writeln(MyFile, MyString);
>   CloseFile(MyFile);

> end;

> //------------------------------------

> In my file called Test.exe MyString has been concatenated.
> To 'Hello'.

> It should have been 'Hello     '.

> There must be something that is wrong here or what??

> Can some one tell me how to deal with this.

> Sincerely Hans

Re:Strings declared with constant length.


In article <34226fca.19370...@cronkite.d48.lilly.com>,

Quote
Roux_N...@Lilly.Com (Nick Roux) wrote:
>string[10] does not specify a constant length of 10, it only specifies
>a maximum length of 10.

So what happens when you declare string[10] for a member in a
packed record? Doesn't it use all the characters, but truncates each
member of the record?
Will you get different lengths on all the records then?
Doesn't exactly make it easy to move them around, accessing specific
members using pointers etc..
Would you need to use format() or something every time you want to write
a value, to be sure you get the right length? And then would you need to trim
the values when you read them?

--
|| Bjorn K. Nilssen      // http://home.sn.no/~bjoernk/  // mainly 3D ||

Re:Strings declared with constant length.


Hi!

  A variable of a fixed length like f.ex. MyString[10] does occupy the
length specified + 1 in memory or in a record based file!  
The first character in such a variable is really character 0 or:
MyString[0]. This character is the actual length of the text in that
variable. Here's an example:

var MyString : string[10];

begin
  MyString := 'Hello';
  ...
  ...
This means that each character location in the variable contains:
    MyString[0] = #5 <--- The actual length of the used text!!
    MyString[1] = 'H'
    MyString[2] = 'e'
    MyString[3] = 'l'
    MyString[4] = 'l'
    MyString[5] = 'o'
    MyString[6] = '?' <--- Unused...so it can be whatever... A good way of
handling this is to fill the record with 0 before using it in a Record
based file.
    MyString[7] = '?'
    MyString[8] = '?'
    MyString[9] = '?'
    MyString[10] = '?'

  This means 11 bytes in total each 10 bytes length strings occupies.
  You can test this by adding a line like:
    ShowMessage(inttostr(Sizeof(MyString));
  The dialog box will tell you:  11

  A variable of the type STRING is quite another issue in the 32 bit
environment. This variable is in fact a pointer to a string and has no
ZERO'th byte that tells the length - This type of a variable can not be
used in a files record. But as soon as you use a fixed length variable the
rule is as I told about above!

  Hope this explains it!
  Regards,
  Bjorn, TransSoft
--
 __  __/  _/
    /    /__
   /       /
 _/   /___/

=======================================================================
           TransSoft Ltd - http://www.transsoft.com
"TransSoft's Mail Control - The Multiple Award Winning Email Client..."
=======================================================================

Bjorn-Kare Nilssen <bjoe...@sn.no> wrote in article
<+L5I0gmCgkaZ09...@sn.no>...

Quote
> In article <34226fca.19370...@cronkite.d48.lilly.com>,
> Roux_N...@Lilly.Com (Nick Roux) wrote:
> >string[10] does not specify a constant length of 10, it only specifies
> >a maximum length of 10.

> So what happens when you declare string[10] for a member in a
> packed record? Doesn't it use all the characters, but truncates each
> member of the record?
> Will you get different lengths on all the records then?
> Doesn't exactly make it easy to move them around, accessing specific
> members using pointers etc..
> Would you need to use format() or something every time you want to write
> a value, to be sure you get the right length? And then would you need to
trim
> the values when you read them?

> --
> || Bjorn K. Nilssen      // http://home.sn.no/~bjoernk/  // mainly 3D ||

Re:Strings declared with constant length.


Quote
bjoe...@sn.no (Bjorn-Kare Nilssen) wrote:
>In article <34226fca.19370...@cronkite.d48.lilly.com>,
>Roux_N...@Lilly.Com (Nick Roux) wrote:
>>string[10] does not specify a constant length of 10, it only specifies
>>a maximum length of 10.

>So what happens when you declare string[10] for a member in a
>packed record? Doesn't it use all the characters, but truncates each
>member of the record?
>Will you get different lengths on all the records then?

The record will always be the same size.

The space allocated in the record will be 11 bytes. But you can put a
shorter string into the member

Record.member := 'fred';

In this case the remaining unused 6 bytes will be undefined.

==
Bob Small

Re:Strings declared with constant length.


In article <3425c307.21299...@news.melbpc.org.au>,

Quote
r...@melbpc.org.au (Robert Small) wrote:
>bjoe...@sn.no (Bjorn-Kare Nilssen) wrote:

>>In article <34226fca.19370...@cronkite.d48.lilly.com>,
>>Roux_N...@Lilly.Com (Nick Roux) wrote:
>>>string[10] does not specify a constant length of 10, it only specifies
>>>a maximum length of 10.

>>So what happens when you declare string[10] for a member in a
>>packed record? Doesn't it use all the characters, but truncates each
>>member of the record?
>>Will you get different lengths on all the records then?

>The record will always be the same size.

>The space allocated in the record will be 11 bytes. But you can put a
>shorter string into the member

>Record.member := 'fred';

>In this case the remaining unused 6 bytes will be undefined.

This is not good news at all, but thanks anyway...

So when I have defined a record like this:

type MyRec packed record
     s1 : string[10];
     s2 : string[20];
     s3 : string[30];
     s4 : string[20];
    end;

I end up with a record that occupies 84 bytes, and not 80, as one would guess?
Which means you won't be able to move this to a file as an 80-byte record?
When you have many thousands of such records in memory that needs to be
written to a file, you can't possibly have to write every single field of
the record separately?
There has to be another way to do it?
What if you use array[0..9] of string instead?

Needless to say(?) I'm just working with this at the moment...
I have already declared a lot of different record types, but I haven't
started trying thme yet. It didn't occur to me that a string declared as
a fixed length would actually m\not be that length after all..
I have to write 80byte records to file, with #13#10 after each line.
But I can not have any "descriptor bytes" in between my record's fields.
That's why I'm using packed records..
I was planning to use BlockWrite and BlockWrite or TFileStream, pointing to
the record. But I guess thta can't be done then?

Quote

>==
>Bob Small

--
|| Bjorn K. Nilssen      // http://home.sn.no/~bjoernk/  // mainly 3D ||

Re:Strings declared with constant length.


Quote
bjoe...@sn.no (Bjorn-Kare Nilssen) wrote:
>What if you use array[0..9] of string instead?

Yes, for example

type MyRec packed record
     s1 : array[0..9] of char;
     s2 : array[0..19] of char;
     s3 : array[0..29] of char;
     s4 : array[0..19] of char;
     s5 : array[0..1] of char;
 end;

This is 82 bytes long.
But you set s5 = #13#10 and then you don't need to always add this
after each 80 byte write or skip over it to get to the next 80 byte
read.
You then use BlockRead/BlockWrite to always use multiples of 82.

BTW, this almost sound like you are reading and writing mainframe data
files of 80 byte length.

You may need to be able to convert between strings and arrays.

String[10] <-> array[0..9] of char

==
Bob Small

Other Threads