Page 1 of 2 1 2 LastLast
Results 1 to 15 of 24

Thread: print loopje

  1. #1
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289

    print loopje

    Hoi

    Ik probeer iets simpels voor elkaar te krijgen maar krijg niet de gewenste output.
    ik heb een file (binary) wat ik inlees, vervolgens wil ik ik de waardes op het scherm printen met een count van MaxChars.

    File:
    12345678

    Output:
    123
    456
    78

    Kan iemand me even een zetje de juiste richting in geven :-)

    Alvast bedankt.


    Code:
    program KeyToArray;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils,
      System.Classes;
    
    {Content file: testfile.txt:
    12345678
    
    Expected output (Maxchars = 2)
    123
    456
    78
    }
    
    
    
    
    const
      FileIn  = '.\testfile.txt';
      FileOut = '.\testfile.out';
      MaxChars = 2;
    
    
    var
      MS        : TMemoryStream;
      SL        : TStringList;
      Current   : integer;
      I         : integer;
      J         : integer;
      B         : Byte;
      S         : string;
    begin
      S := '';
    
      MS := TMemoryStream.Create;
      SL := TSTringList.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        if MS.Size > 0 then
          for I := 0 to MS.Size -1 do
            if MS.Read(B,1) > 0 then
              SL.Add('$' + B.ToHexString);
    
    
        // Process StringList
        S       := '';
    
        WriteLn(format ('REPEAT  | MaxChars %-3d | S1 %s',[MaxChars, S]));
    
        Current := 0;
        repeat
          begin
            J := 0;
            while J < MaxChars do
              begin
                S := S + ' ' + SL[Current];
                if J = MaxChars then
                  begin
                    J := 0;
                    Current := Current + MaxChars;
                  end
                else
                  inc(J);
                WriteLn(format ('WHILE   | MaxChars %-3d | S1 %s',[MaxChars, S]));
              end;
          end;
        until Current = SL.Count -1;
    
        WriteLn ('Ended');
    
    
      finally
        SL.Free;
        MS.Free;
      end;
    
      readln;
    end.

  2. #2
    Het is me niet helemaal duidelijk wat je precies probeert te doen, maar hier een paar opmerkingen/tips als commentaar toegevoegd aan jouw code.

    Code:
    program KeyToArray;
    
    {$APPTYPE CONSOLE}
    {$R *.res}
    
    uses
      System.SysUtils,
      System.Classes;
    
    { Content file: testfile.txt:
      12345678
    
      Expected output (Maxchars = 2)
      123
      456
      78
    }
    
    const
      FileIn = '.\testfile.txt';
      FileOut = '.\testfile.out';
      MaxChars = 2;
    
    var
      MS: TMemoryStream;
      SL: TStringList;
      Current: integer;
      I: integer;
      J: integer;
      B: Byte;
      S: string;
    
    begin
      S := '';
    
      MS := TMemoryStream.Create;
      SL := TStringList.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        if MS.Size > 0 then
          for I := 0 to MS.Size - 1 do
            if MS.Read(B, 1) > 0 then
              SL.Add('$' + B.ToHexString);
    
        // Process StringList
        S := '';
    
        WriteLn(format('REPEAT  | MaxChars %-3d | S1 %s', [MaxChars, S]));
    
        Current := 0;
        repeat
        begin
          J := 0;
          while J < MaxChars do
          begin
            S := S + ' ' + SL[Current]; // <== Als SL.Add op r45 niet wordt uitgevoerd, dan geeft dit een out of bounds exception.
            if J = MaxChars then  // <== Dit is nooit true omdat J < MaxChars (while J < MaxChars do)
            begin
              J := 0;
              Current := Current + MaxChars; // <== Dit wordt ook nooit uitgevoerd.
            end
            else
              inc(J);
            WriteLn(format('WHILE   | MaxChars %-3d | S1 %s', [MaxChars, S]));
          end;
        end;
        until Current = SL.Count - 1; // <== Omdat Current niet veranderd zal dit nooit true worden, behalve als SL.Count = 1.
    
        WriteLn('Ended');
    
      finally
        SL.Free;
        MS.Free;
      end;
    
      readln;
    
    end.

  3. #3
    Ik begrijp niet zo goed wat je wilt.
    Je voorbeeld output in je code komt niet echt overeen met wat je programmeert.
    Je verwacht ouput:
    1 2 3
    4 5 6
    7 8

    Maar je slaat alle bytes op in je stringlist als hexadecimale representatie voorafgegaan door een '$'.
    Je gaat dus nooit de output krijgen die je wilt.

    Waarom is die stringlist eigenlijk nodig?
    Je kunt toch gewoon byte voor byte lezen (vanuit je stream) en converteren als je schrijft?
    Pseudocode:
    Code:
    counter := 0;
    while not end of stream do
      read a byte
      if counter = maxchars then writeln
      write byte as hex + space
      inc counter
    end while
    Overigens, de check voor MS.Read(B,1) > 0 lijkt me wat paranoide, gezien je dit in een loop doet tot MS.Size-1.
    Als je per se wilt checken, dan moet je ook consequent zijn, namelujk checken dat MS.Read(B,1)=1, iedere andere waarde is fout.

    Wellicht kun je iets doesn zoals ik in mijn (zeer naïeve implementatie van) http://svn.code.sf.net/p/flyingsheep...hexdump/hd.lpr?

    Bart

  4. #4
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    Quote Originally Posted by luigi View Post
    Het is me niet helemaal duidelijk wat je precies probeert te doen, maar hier een paar opmerkingen/tips als commentaar toegevoegd aan jouw code.

    Code:
    program KeyToArray;
    
    {$APPTYPE CONSOLE}
    {$R *.res}
    
    uses
      System.SysUtils,
      System.Classes;
    
    { Content file: testfile.txt:
      12345678
    
      Expected output (Maxchars = 2)
      123
      456
      78
    }
    
    const
      FileIn = '.\testfile.txt';
      FileOut = '.\testfile.out';
      MaxChars = 2;
    
    var
      MS: TMemoryStream;
      SL: TStringList;
      Current: integer;
      I: integer;
      J: integer;
      B: Byte;
      S: string;
    
    begin
      S := '';
    
      MS := TMemoryStream.Create;
      SL := TStringList.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        if MS.Size > 0 then
          for I := 0 to MS.Size - 1 do
            if MS.Read(B, 1) > 0 then
              SL.Add('$' + B.ToHexString);
    
        // Process StringList
        S := '';
    
        WriteLn(format('REPEAT  | MaxChars %-3d | S1 %s', [MaxChars, S]));
    
        Current := 0;
        repeat
        begin
          J := 0;
          while J < MaxChars do
          begin
            S := S + ' ' + SL[Current]; // <== Als SL.Add op r45 niet wordt uitgevoerd, dan geeft dit een out of bounds exception.
            if J = MaxChars then  // <== Dit is nooit true omdat J < MaxChars (while J < MaxChars do)
            begin
              J := 0;
              Current := Current + MaxChars; // <== Dit wordt ook nooit uitgevoerd.
            end
            else
              inc(J);
            WriteLn(format('WHILE   | MaxChars %-3d | S1 %s', [MaxChars, S]));
          end;
        end;
        until Current = SL.Count - 1; // <== Omdat Current niet veranderd zal dit nooit true worden, behalve als SL.Count = 1.
    
        WriteLn('Ended');
    
      finally
        SL.Free;
        MS.Free;
      end;
    
      readln;
    
    end.
    Ik had mijn laatste poging als code toegevoegd, welke ook niet werkte.
    Zal er nog eens doorheen lopen.

    Bedankt voor je reactie

  5. #5
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    Quote Originally Posted by Bart B View Post
    Ik begrijp niet zo goed wat je wilt.
    Je voorbeeld output in je code komt niet echt overeen met wat je programmeert.
    Je verwacht ouput:
    1 2 3
    4 5 6
    7 8

    Maar je slaat alle bytes op in je stringlist als hexadecimale representatie voorafgegaan door een '$'.
    Je gaat dus nooit de output krijgen die je wilt.

    Waarom is die stringlist eigenlijk nodig?
    Je kunt toch gewoon byte voor byte lezen (vanuit je stream) en converteren als je schrijft?
    Pseudocode:
    Code:
    counter := 0;
    while not end of stream do
      read a byte
      if counter = maxchars then writeln
      write byte as hex + space
      inc counter
    end while
    Overigens, de check voor MS.Read(B,1) > 0 lijkt me wat paranoide, gezien je dit in een loop doet tot MS.Size-1.
    Als je per se wilt checken, dan moet je ook consequent zijn, namelujk checken dat MS.Read(B,1)=1, iedere andere waarde is fout.

    Wellicht kun je iets doesn zoals ik in mijn (zeer naïeve implementatie van) http://svn.code.sf.net/p/flyingsheep...hexdump/hd.lpr?

    Bart
    Waarom zou je met een stringlist niet de gewenste output kunnen krijgen? Een SL[I] geeft toch netjes de waardes weer alleen niet in de format die ik wil.
    Zal jouw psuedo code eens omzetten en kijken of ik het dan wel werkend krijg.

    Bedankt voor je reactie

  6. #6
    Quote Originally Posted by Herby View Post
    Waarom zou je met een stringlist niet de gewenste output kunnen krijgen?
    Dat is ook niet wat ik zeg.
    Ik denk alleen dat die stringlist niet nodig is, en dat die de code ingewikkelder maakt dan nodig.

    Bart

  7. #7
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    Quote Originally Posted by Bart B View Post
    Dat is ook niet wat ik zeg.
    Ik denk alleen dat die stringlist niet nodig is, en dat die de code ingewikkelder maakt dan nodig.

    Bart
    oke, dan las ik het verkeerd :-)
    Heb er nu dit van gemaakt, is nog niet helemaal in orde, daar kijk ik morgen wel naar.

    Code:
    program KeyToArray1;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils,
      System.Classes;
    
    const
      FileIn  = 'testfile.txt';
      FileOut = 'testfile.out';
      MaxChars = 2;
    
    var
      MS      : TMemoryStream;
      Counter : integer;
      B       : Byte;
      S       : string;
    
    begin
      MS := TMemoryStream.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        Counter := 0;
        while MS.Position <= MS.Size do
          begin
            MS.Read(B,1);
            if Counter <= MaxChars then
              begin
                S := S + ' $' + B.ToString;
              end
            else
                WriteLn (S);
    
            Inc(Counter);
          end;
    
      finally
        MS.Free;
      end;
    
      readln;
    
      {
    counter := 0;
    while not end of stream do
      read a byte
      if counter = maxchars then writeln
      write byte as hex + space
      inc counter
    end while
     }
    
    end.

  8. #8
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    Ik eindig weer in dezelfde situatie waarbij ik niet het gewenste resultaat krijg.
    Bedoeling is dat iedere keer 3 op een regel geprint worden, ipv iedere keer dezelfde regels.
    Oftewel, lees file, krijgt 8 bytes terug, loop daar doorheen en print iedere 3 karakters.

    Verwachte output:
    $31 $32 $33
    $34 $35 $36
    $37 $38

    Werkelijke output:
    $31 $32 $33
    out of memory

    Code:
    counter := 0;
    while not end of stream do
      read a byte
      if counter < maxchars then S = S + Hex(Byte)
      if counter = maxchars then 
          write byte as hex + space
      inc counter
    end while
    Code:
    program KeyToArray;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils,
      System.Classes;
    
    const
      FileIn  = 'testfile.txt';
      FileOut = 'testfile.out';
      MaxChars = 2;
    
    var
      MS      : TMemoryStream;
      Counter : integer;
      B       : Byte;
      S       : string;
    
    begin
      MS := TMemoryStream.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        Counter := 0;
        while MS.Position <= MS.Size do
          begin
            MS.Read(B,1);
            if Counter <= MaxChars then
              S := S + ' $' + B.ToHexString;
    
            if Counter = MaxChars then
              WriteLn (S);
    
            Inc(Counter);
          end;
    
      finally
        MS.Free;
      end;
    
      readln;
    end.

  9. #9
    Zie commentaar.
    Code:
    begin
      MS := TMemoryStream.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        Counter := 0;
        while MS.Position <= MS.Size do  // <== Blijft altijd true en dus zit je in een eindeloze lus.
          begin
            MS.Read(B,1);
            if Counter <= MaxChars then // <== Dit zorgt ervoor dat je slechts 3 outputs krijgt.
              S := S + ' $' + B.ToHexString;
    
            if Counter = MaxChars then
              WriteLn (S);
    
            Inc(Counter);
          end;
    
      finally
        MS.Free;
      end;
    
      readln;
    end.

  10. #10
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    Quote Originally Posted by luigi View Post
    Zie commentaar.
    Code:
    begin
      MS := TMemoryStream.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        Counter := 0;
        while MS.Position <= MS.Size do  // <== Blijft altijd true en dus zit je in een eindeloze lus.
          begin
            MS.Read(B,1);
            if Counter <= MaxChars then // <== Dit zorgt ervoor dat je slechts 3 outputs krijgt.
              S := S + ' $' + B.ToHexString;
    
            if Counter = MaxChars then
              WriteLn (S);
    
            Inc(Counter);
          end;
    
      finally
        MS.Free;
      end;
    
      readln;
    end.
    Code:
    begin
      MS := TMemoryStream.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        Counter := 0;
        {while MS.Position <= MS.Size do  // <== Blijft altijd true en dus zit je in een eindeloze lus.}
        while MS.Position < MS.Size do  // aangepast, dit resulteert in output: $31 $32 $33
          begin
            MS.Read(B,1);
            {if Counter <= MaxChars then // <== Dit zorgt ervoor dat je slechts 3 outputs krijgt.}
            if Counter <= MaxChars then // <== Dit is waar het ook iedere keer mis gaat in eerdere pogingen, maw ik krijg niet alle regels die ik zou willen
              S := S + ' $' + B.ToHexString;
    
            if Counter = MaxChars then
              WriteLn (S);
    
            Inc(Counter);
          end;
    
      finally
        MS.Free;
      end;
    
      readln;
    end.

  11. #11
    Als je "MaxChars" verhoogt, dan zul je meer regels zien. Het is me alleen niet helemaal duidelijk wat je doel is met MaxChars.

  12. #12
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    Quote Originally Posted by luigi View Post
    Als je "MaxChars" verhoogt, dan zul je meer regels zien. Het is me alleen niet helemaal duidelijk wat je doel is met MaxChars.
    Als ik MaxChars verhoog dat krijg ik er meer op één regel en dat wil ik dus niet

    Read File
    Loop door alle items
    print MaxChars per regel (bij 8 items in file heb je dus 3 regels, 2 regels van 3 en 1 regel van 2 items)

  13. #13
    Je zou ook de debugger kunnen gebruiken. Dan zie je waar en waarom het fout gaat.
    Het is een consoleprogramma, maar deze code kan je ook in een Application stoppen en zo debuggen.

    Maar ter zake:
    Je hoogt Counter steeds met 1 op. Je vergelijkt deze met MaxChars en wanneer ze beide gelijk zijn doe je een WriteLn.
    Omdat je Counter voortdurend ophoogt, terwijl MaxChars een vaste waarde heeft, wordt de gewenste WriteLn maar één keer uitgevoerd.
    Het gevolg is een groter groeiende string die uit zijn voegen loopt, terwijl niets wordt geprint.

    En nu ik toch bezig ben: Hoe wordt de string S voor een nieuwe regel op '' gezet, dus leeg gemaakt?

    Succes!

  14. #14
    Win32.Trojan.Heur.Herby
    Join Date
    Dec 2003
    Location
    Nuenen of all places
    Posts
    289
    Quote Originally Posted by MaartenW View Post
    Je zou ook de debugger kunnen gebruiken. Dan zie je waar en waarom het fout gaat.
    Het is een consoleprogramma, maar deze code kan je ook in een Application stoppen en zo debuggen.

    Maar ter zake:
    Je hoogt Counter steeds met 1 op. Je vergelijkt deze met MaxChars en wanneer ze beide gelijk zijn doe je een WriteLn.
    Omdat je Counter voortdurend ophoogt, terwijl MaxChars een vaste waarde heeft, wordt de gewenste WriteLn maar één keer uitgevoerd.
    Het gevolg is een groter groeiende string die uit zijn voegen loopt, terwijl niets wordt geprint.

    En nu ik toch bezig ben: Hoe wordt de string S voor een nieuwe regel op '' gezet, dus leeg gemaakt?

    Succes!
    Ik gebruik ook de debugger maar het kwartje valt gewoon niet of ik zie simpelweg gewoon niet waar het mis gaat.
    Blijf uitkomen dat er of heel veel dezelfde regels geprint worden of dat er te weinig geprint wordt, hoe dan ook, niet de output die ik wil.

    Code:
    const
      FileIn  = 'testfile.txt';
      FileOut = 'testfile.out';
      MaxChars = 2;
    
    var
      MS      : TMemoryStream;
      Counter : integer;
      B       : Byte;
      S       : string;
    
    begin
      MS := TMemoryStream.Create;
      try
        // Read file as binary
        MS.LoadFromFile(FileIn);
        MS.Position := 0;
        Counter := 0;
        S := '';
    
        while MS.Position <= MS.Size do
          begin
            MS.Read(B,1);
            if Counter < MaxChars then
              S := S + ' $' + B.ToHexString;
    
            if Counter = MaxChars then
              begin
                S := S + ' $' + B.ToHexString;
                WriteLn (S);
                S := '';
                Counter := 0;
              end;
    
            Inc(Counter);
    
            if MS.Position = MS.Size then
              break;
          end;
    
      finally
        MS.Free;
      end;
    
      WriteLn ('Finished');
      readln;
    output nu:
    $31 $32 $33 <-- oke $31 $32 $33
    $34 $35 <-- zou moeten zijn $34 $35 $36
    $36 $37 <-- zou moeten zijn $37 $38
    Finished

  15. #15
    zoiets?
    while MS.Position < MS.Size do
    begin
    MS.Read(B,1);
    S := S + ' $' + B.ToHexString;
    if (ms.position mod 3 =0) then
    begin
    WriteLn (S);
    S := '';
    end;
    end;
    if s<>'' then writeln(s);
    PS Zelf vindt ik die spatie als start in s nooit echt "mooi" en gebruik ik een ifthen om het te regelen zoiets als ifthen(s='','$',' $')

    PSS als de spatie er altijd voorstaat dan is de lengte van de string altijd hetzelfde namelijk 4 x bytes, dan kan je ook testen op length(s)= 4 x maxchars (met maxchars op 3) en als die lengte klopt dan writeln(s) en s:=''

    PSSS en die mod 3 kan uiteraard mod maxchars worden maar dan wel maxchars op 3 zetten. Iets wat ik zelf altijd zo-wie-zo zou doen aangezien een maxchars op 2 zetten terwijl je 3 bedoelt maakt de code niet makkelijker om te lezen/begrijpen voor een ander.

    Laatste PS (denk ik
    Je bug zit in het feit dat je de counter altijd inc, zelfs als je de writeln hebt gedaan. Ik zou zelf de counter als eerste inc (dus direct naar de while) en dan maxchars (ja daar is hij weer) op 3 zetten.
    Last edited by Miep; 26-Nov-21 at 12:16.

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 2 users browsing this thread. (0 members and 2 guests)

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
  •