Results 1 to 7 of 7

Thread: array (understanding?) problem

  1. #1

    array (understanding?) problem

    Hi all

    I've got a (for me) very strange problem. I want to read data from a file via TFileStream into an array.
    After the first loop, GMapTempBuffer[0, 0] contains a string like 'test1'. Everything ok so far.
    After the next loop I would expect [0, 0] to contain still 'test1' and [1, 0] maybe 'test2'. But no, [0, 0] has been overwritten with 'test2'. [1, 0] is still empty.
    Maybe I'm only have a big thinking-problem here, but I don't understand this. Can anybody help? Hope the explanation is not too stupid. :?

    Here's the code for that stuff:
    Code:
    var
     GMapTempBuffer: array[0..31, 0..31] of string;  
     c: string;
    (...)
    
    FileStream := TFileStream.Create(FileName, fmOpenRead);
       try
         for y := 0 to 31 do
          begin
            for x := 0 to 31 do
            begin
              FileStream.ReadBuffer(PChar(c)^, len);  
              GMapTempBuffer[x, y] := c;
              GroundMap[x, y].Picfilename := GMapTempBuffer[x, y];
            end;
          end;
       except begin
        result := false;
        FileStream.Free;
        exit;
       end;
      end;
    Thanx for any help,

    Sven
    42 is the answer to all questions.
    <br />But what is the question to all answers?

  2. #2

    array (understanding?) problem

    What format is the file you are reading in? You don't seem to be reading the length of the string ("len") anywhere or setting the size of the string with SetLength().

    As a reference, here are a pair of generic procedures I use to write and read strings to and from streams. The Length of the string is written to the stream first, then the string data; to read the length is then read back and SetLength called to set the size of the string before reading the data back.
    [pascal]procedure WriteStringToStream(Stream: TStream; const S: String);
    var
    StrLen: Integer;
    begin
    { Get length of string }
    StrLen := Length(S);
    { Write length of string to stream }
    Stream.WriteBuffer(StrLen, SizeOf(StrLen));
    { Write string to stream }
    Stream.WriteBuffer(S[1], (StrLen * SizeOf(Char)));
    end;

    procedure ReadStringFromStream(Stream: TStream; out S: String);
    var
    StrLen: Integer;
    begin
    { Read length of string from stream }
    Stream.ReadBuffer(StrLen, SizeOf(StrLen));
    { Set length of string }
    SetLength(S, StrLen);
    { Read string from stream }
    Stream.ReadBuffer(S[1], (StrLen * SizeOf(Char)));
    end;[/pascal]
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  3. #3

    array (understanding?) problem

    Well, the file i am working with is a map-file for my game, so in the game I won't write to it, only read. Maybe in a map-editor if one will exist someday..

    But the length doesn't matter, every string I read has a length of 5 characters. I'm doing the setlength thing in my code, but I forgot to post it.
    I changed the ReadBuffer line now and with your code it seems to work.
    thanx for that.

    sven
    42 is the answer to all questions.
    <br />But what is the question to all answers?

  4. #4

    array (understanding?) problem

    hm, I was wrong, it doens't really work. Well it's reading, but only the first 5 charakters of the file.
    With the count parameter in ReadBuffer I only can choose how many bytes should be read from the file, not where the procedure starts to read, can't i?
    How can I make it read always the following 5 charakters, not the first ones?

    FlyingFish
    42 is the answer to all questions.
    <br />But what is the question to all answers?

  5. #5

    array (understanding?) problem

    ReadBuffer will always start from the next byte after the previous one read, so it should work. It might help if you posted some more of your code.
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  6. #6

    array (understanding?) problem

    ok, here's the function where I use all the stream stuff.
    TMapTile is an object, only the picfilename property is important for here. picfilename is of course a string.

    Code:
    var
     GroundMap&#58; array&#91;0..31, 0..31&#93; of TMapTile;
    
    &#40;...&#41;
    
    function LoadGroundMapFromFile&#40;FileName&#58; string&#41;&#58; Boolean;
    var
      FileStream&#58; TFileStream;
      c&#58; string;
      len&#58; longint;
      x, y&#58; Word;
     begin
       result &#58;= true;
       len &#58;= 5;
       x &#58;= 5;
       y &#58;= 0;
       setlength&#40;c, len&#41;;
       FileStream &#58;= TFileStream.Create&#40;FileName, fmOpenRead&#41;;
       try
         for y &#58;= 0 to 31 do
          begin
            for x &#58;= 0 to 31 do
            begin
              FileStream.ReadBuffer&#40;c&#91;1&#93;,  &#40;len * SizeOf&#40;Char&#41;&#41;&#41;;
              GroundMap&#91;x, y&#93;.Picfilename &#58;= c;
            end;
          end;
       except begin
        result &#58;= false;               
        FileStream.Free;
        exit;
       end;
      end;
      FileStream.Free;
     end;
    sven
    42 is the answer to all questions.
    <br />But what is the question to all answers?

  7. #7

    array (understanding?) problem

    You will need to call SetLength() every iteration of the loop, before the call to ReadBuffer(), even though the strings are the same length, since this guarantees that "c" is a unique string; otherwise all the values in the array will point to the same string.
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •