Board index » delphi » Reading a Null-Terminated String from a Binary File

Reading a Null-Terminated String from a Binary File

I wrote a console Delphi app that reads a binary file created by a C
program.  Basically, the C program wrote an array of structs to a file, and
I'm trying to read each of those structs into a record in Delphi.  The only
challenge I've run into is interpreting null-terminated strings within
those C structs.

The method I used was to have an array[0..17] of char field in the record
(obviously, the numbers are particular to my application).  I read all the
record data in via blockread() calls on an untyped file.

Apparently, passing such an array to write() makes Delphi interpret it as a
null-terminated string, which is exactly what I want.

Is this the standard solution for this problem?  Any gotchas I should be
aware of?

(If it matters, I've been programming Delphi for four days, and this was
done purely as a teaching exercise.)

 

Re:Reading a Null-Terminated String from a Binary File


Quote
Nero wrote in message ...
>I wrote a console Delphi app that reads a binary file created by a C
>program.  Basically, the C program wrote an array of structs to a file,
and
>I'm trying to read each of those structs into a record in Delphi.  The
only
>challenge I've run into is interpreting null-terminated strings within
>those C structs.

>The method I used was to have an array[0..17] of char field in the record
>(obviously, the numbers are particular to my application).  I read all the
>record data in via blockread() calls on an untyped file.

>Apparently, passing such an array to write() makes Delphi interpret it as
a
>null-terminated string, which is exactly what I want.

>Is this the standard solution for this problem?  Any gotchas I should be
>aware of?

This would appear to be either a bug or undocumented behaviour in Write.
It's not actually unreasonable, but not today The Delphi Way (not that
you would or should care much about that at this point). It probably goes
back to old Pascal days, when an array of char was the best one could do
for a string. Obviously, for variable-length strings, this doesn't quite
work, because arrays could not then be variable length (this is a Delphi-
introduced feature). Treating the content as an ASCIIZ string is in fact
very reasonable.

Turbo Pascal introduced what are now called short strings, which allocate
the maximum declared size and use an extra byte at the beginning to store
the current length. It was at the time a vast improvement, even though
limited to 255 characters, and not very efficient memory-wise.

Delphi introduced long strings, which are the current state of the art.
Reference-counted, allocated and reallocated on the heap, copy-on-write.
Efficient, robust, and easy to use at the cost of a few bytes of overhead.
And: compatible with null-terminated strings.

If you don't actually _do_ much with your strings, I'd recommend to keep
doing what you do now. If there is some significant string processing in
your program, you can assign the arrays to long string variables. This
makes a copy to the preferred type of long string. The Delphi type to use
for null-terminated strings is PChar. Most combinations of these are
assignment-compatible; keep an eye out for what exactly happens. Sometimes
it's a copy, sometimes merely an alias.

This is of course a topic that many people run into as they try to coexist
with other languages, particularly C. Ample information is available in
the help files.

Groetjes,
Maarten Wiltink

Other Threads