Questing on String
peter at agnes.dida.physik.uni-essen.de
Sat Oct 25 13:06:57 CEST 1997
According to Thomas Tan:
> How does writeln(astring) work,
I am not sure whether I understand your question ...
To use `writeln', just do
writeln ( MyIntegerValue : 6, MyRealValue : 10 : 4, MyStringValue : 7 );
42 3.1415 Hallo!
writeln ( 'Answer = ', MyIntegerValue );
Answer = 42
If you want to know how `writeln' works internally, please look at the
GPC source, file `rts.c', and in the subdirectory `rts' at the files
`rts-write.c' and `rts-wrtinc.c'. If you have more questions about that,
please post them on this list.
> is the string null terminating?
No, but GPC has an additional string type `CString' (or `PChar' for BP
compatibility) which *is* null-terminated. If you have, for example,
a null-terminated string you want to pass to an external function that
wants to have such a string as a parameter (this holds for many external
functions written in C), you can use `CString' as follows:
(*$X+*) (* Enable "extended syntax" if you want to use `CString' *)
Function SetEnv ( Name, Value: CString; overwrite: Integer ): Integer; C;
Function GetEnv ( Name: CString ): CString; C;
SetEnv ( 'TEST_ENV', 'OK', 1 );
S:= GetEnv ( 'TEST_ENV' );
writeln ( S );
> If so, what is the character of null?
Not too surprisingly, it is `chr ( 0 )' or `#0'. :-) For `CString'.
GPC's native `String' is *not* null-terminated.
And to answer your implicit question about GPC string internals:
GPC's native `String' is a special case of a "schema type". It looks
like a record internally:
String ( n: Integer ) = record
Capacity, length: Integer; (* 8 bytes *)
data: packed array [ 1..n ] of Char; (* n bytes *)
end (* String *);
(* Remark: The above is a perfectly valid type declaration in GNU Pascal
or any other compiler that supports Extended Pascal's schema types. It is,
however, not identically the same as GPC's `String' since the built-in
string functions only work on the built-in string type, but it has the same
structure in memory. *)
When you declare a string variable with "Var Foo: String ( 42 )" (* Now you
see where the round parentheses come from. ;*), the "record field" `Capacity'
gets the value 42 assigned, while `length' and `data' remain undefined until
you assign a value to the string. You can access a string's capacity with
`Foo.capacity' just like a record field.
For dynamical allocation of strings, you can define "Type StringPtr = ^String"
*without* a specified capacity and then give it when `New'ing the variable.
StringPtr = ^String;
New ( Foo, 1042 ); (* allocate a String of maximum length 1042 *)
Foo^:= 'Hello, world!';
writeln ( Foo^.Capacity ); (* yields "1024" *)
writeln ( Foo^ ); (* yields "Hello, world!" *)
Dispose ( Foo );
In addition to these features of Extended Pascal, GPC supports the following
StringPtr = ^String;
Foo:= @'Hello, world!'; (* let `Foo' point to a string constant *)
Foo:= New ( StringPtr, 42 ); (* let `New' act as a function *)
If you want to contribute to the GNU Pascal project, feel free to improve
the existing documentation by adding the things I wrote above (and more;-).
If you do so, please do not forget to post to this list what you are doing
so you can coordinate with others who are currently working on the same
Hope this helps,
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski at uni-essen.de - http://home.pages.de/~peter.gerwinski/ 
maintainer GNU Pascal  - http://home.pages.de/~gnu-pascal/ 
More information about the Gpc