Reputation: 13
I have a problem. Why I can't assign the value of strings to strings, but with chars it works. Why ^^^^^^? Where's string? Why There's the a[i]? Is it because internal representation of strings and chars?
program massive.pas;
type
chars = array [1..255] of char;
var
s,s1: string;
ch1,ch2: chars;
i: integer;
begin
s1 := '';
s := 'abrakadabra';
for i := 1 to 5 do
begin
s1[i] := s[i];
writeln(s1[i],#10,'^^^',s1,'^^^')
end;
ch2 := '';
ch1 := 'abrakadabra';
for i := 1 to 5 do
begin
ch2[i] := ch1[i]
writeln(ch2[i])
end;
writeln('%%%',ch2,'%%%');
for i := 1 to 5 do
writeln('&&&',s1[i],'&&&');
end.
*Output
a
^^^^^^
b
^^^^^^
r
^^^^^^
a
^^^^^^
k
^^^^^^
a
b
r
a
k
%%%abrak%%%
&&&a&&&
&&&b&&&
&&&r&&&
&&&a&&&
&&&k&&&
Upvotes: 1
Views: 328
Reputation: 21033
The main difference between type chars = Array[1..255] of Char
and String
is that a chars
array has a fixed length, while the string has a dynamic length.
You did not say which compiler you use, but I do think that the String
type is what in some Pascal editions is called a ShortString
, with a max length of 255 chars. The space for 255 chars is preallocated and the structure includes a length field, that keeps track of assigned length of the string.
In your example, you assign s1 := '';
in other words the length is set to zero. Then you do a mistake in the for loop
in assigning s1[i] := s[i];
without setting the length of s1.
Subsequent reading of s1
always return an empty string as the length field is 0.
If you would assign the characters to the string, e.g. as:
for i := 1 to 5 do
begin
SetLength(s1, Length(s1)+1);
s1[i] := s[i];
writeln(s1[i],#10,'^^^',s1,'^^^');
end;
then the result would be what you originally expected.
Still better to set the length to the final 5 before the for loop
.
Of course there are other solutions too. One is to not set the length at all, but to concatenate the string in the loop and let it handle the length field by itself:
for i := 1 to 5 do
begin
s1 := s1 + s[i];
writeln(s1[i],#10,'^^^',s1,'^^^');
end;
Edit 24.12.2021:
In a comment you said: But I still don't understand, why, when i wrote s1[1] in the for loop, all worked?
...and presumably refer to this code just before end.
:
for i := 1 to 5 do
writeln('&&&',s1[i],'&&&');
We need to look at the memory layout and know that the first byte of the memory allocated to s1
is the length of the string. It can be referred to as s[0]
. Subsequent bytes hold the characters that make up the stored string and they can be referred to as s[1]..s[n].
The first byte was set to 0 when you wrote (in the very beginning):
s1 := '';
// memory content:
0
|_|_|_|_|_|_|_|_|_| ...
Then you added the characters to s1
by manipulating the memory directly when you wrote in the first for
loop:
s1[i] := s[i];
// content after 5 characters
0 a b r a k
|_|_|_|_|_|_|_|_|_| ...
Because you did not use concatenation (or adjusted the length while you added the characters) the length is still 0.
Then at the end in the last loop, you fetch the characters again by accessing the memory directly, and get the result you do, seemingly correct, but badly misusing the string structure.
Upvotes: 1