0

I am taking VB6 code and translating it to Delphi.

VB6 code that opens a file using sequential order:

Dim bytNumDataPoints As Byte
Dim bytcount as Byte
Dim lintData(0 To 23) As Long
    Input #intFileNumber, bytNumDataPoints
    For bytcount = 0 To (bytNumDataPoints - 1)
        Input #intFileNumber, lintData(bytcount)  '
        lintData(bytcount) = (lintData(bytcount) + 65536) Mod 65536
    Next bytcount

File data:

24  <<<<<<<<<<<< Number Data Points
200  300  400  450  500  600  750  1000  1250  1500  1750  2000  2500  3000  3500  3750  4000  4500  5000  5250  5500  5750  6000  6250  <<<< data

This is some neat stuff. You keep calling Input and fill out the array. As far I know there is no equivalent for this phenomena in Delphi. You cannot use ReadLn like that, right? To me in Delphi you would have to

ReadLn(F, S);  //S is a string
z.Delimiter := ' '; //z is a stringlist
z.DelimitedText := S;  //and then breakdown the array

Any thought? Thanks.

Deanna
  • 23,876
  • 7
  • 71
  • 156
t j
  • 413
  • 1
  • 7
  • 12
  • So you're going to read a text file, which contains series of numeric values, where on the first line is the count of numbers in the second line and in the second line the numbers are separated by double space, right ? – TLama Feb 26 '13 at 16:09
  • Your proposed solution is fine. But don't use legacy `Readln`. Use modern IO. And there's no need for the number of data points. Your VB6 code is broken too. Note the way you decide that there will be 24 points when you allocate the array. You should allocate your array after reading in the number of data points, in the VB6 code. – David Heffernan Feb 26 '13 at 16:24
  • This looks like a good candidate for streaming – Leonardo Herrera Feb 26 '13 at 16:34
  • Okay, David. You dangled a carrot. Modern IO? I googled it and found nothing. – t j Feb 26 '13 at 16:35
  • Splitting string in Delphi: http://stackoverflow.com/search?q=%5Bdelphi%5D+split+string But if for some reason you don't want to - i see no problem i nre-implementing this a la Basic. – Arioch 'The Feb 26 '13 at 16:37
  • Leonardo, I used streaming first and may go back to it. But this is a very complicated file with over 1000 lines of data with varying array lengths. It is perfect for VB6 but a real challenge for Delphi. – t j Feb 26 '13 at 16:37
  • If there is about 1000 lines, then surely two chained stringlist would be easier to use. Load into one stringlist, and iterate through it, and then use secondary stringlist to split each line and trim it before passing to StrToInt; – Arioch 'The Feb 26 '13 at 16:44
  • @t j: No challenge for Delphi, if you want to use old style I/O using Read and Readln. It should not be too hard to translate the VB code to old style Pascal I/O, but I guess most people would first have to experiment with it again, as most don't use that stuff anymore. The approach using a stringlist and then some code that separates the values on each line - using another stringlist - is probably faster, but not as straightforward. – Rudy Velthuis Feb 26 '13 at 17:14
  • Up 1000 lines, I might go for a bit of optimisation then. when it looked like 24 values it seemed too trivial to bother with. My problem with the thinking behind this question, is that a direct translation of the code is the right way to go. Invariably not in my experience. How attached are you to that double space delimiter, and when you've read in all the numbers, are you doing numeric things with them or string type things? – Tony Hopkinson Feb 26 '13 at 18:53
  • Because if reading and writing with strings is okay, and you reformat the data file to standard csv you could do this generically with a handful of VCL calls. Which would be the way you would have approached it if weren't in VB6 mode. – Tony Hopkinson Feb 26 '13 at 18:57

3 Answers3

3

Use Read instead of Readln; Something like this:

var
  ArrLng, Index: Integer;
  Arr: array of Integer;
  F: Text;
begin
  Assign(F, 'your-fie-name');
  OpenFile(F);
  try
    Readln(F, ArrLng);
    SetLength(Arr, ArrLng);
    Index := 0;
    while (not Eof(F)) and (Index < ArrLng) do
    begin
      Read(F, Arr[Index]);
      Inc(Index);
    end;
  finally
    CloseFile(F);
  end;
end;
Arioch 'The
  • 15,799
  • 35
  • 62
Abelisto
  • 14,826
  • 2
  • 33
  • 41
2

Splitting string would be generally better approach, with StringList or without.

But i think you can also use old Pascal approach there. Just forget about end-of-line, you probably don't need it.

var F: TextFile; I, J, K: integer;
begin
...
ReadLN(F, J);
for i := 1 to J do 
  Read(F, K);
...
end

But i think it would only be nice for niche approaches (like out of memory) and overall SplitString approach would be faster.

And if you have multi-line files, then two chained stringlist would be IMHO most easy approach, providing those files are not GB-sized.

https://stackoverflow.com/a/14454614/976391 or utilizing more SL features - https://stackoverflow.com/a/14649862/976391

Community
  • 1
  • 1
Arioch 'The
  • 15,799
  • 35
  • 62
0

The TStringList class and it's LoadFromFile method. It's got delimiter properties as well.

When you are doing Delphi, treat it like .net. If there's something that should be there, it is, you just haven't found it yet. You can chuck the number of values thing away as well.

Tony Hopkinson
  • 20,172
  • 3
  • 31
  • 39
  • intersting mark down. If i didn't use tstringlist to do this in delphi, I'd sack myself... – Tony Hopkinson Feb 26 '13 at 17:07
  • +1, I don't see why this got a down-vote. expect maybe because you didn't explain a bit about "It's got delimiter properties as well" – kobik Feb 26 '13 at 17:43
  • I don't see why it's upvoted. The question already demonstrates good knowledge the delimiter properties. – David Heffernan Feb 26 '13 at 17:49
  • @DavidHeffernan, The OP used Pascal IO to read the file lines, and used TStringList delimiter to parse each line. the above suggest to load the entire file using a TStringList. – kobik Feb 26 '13 at 17:52
  • @kobik That may be ever so slightly better. But do you really think this is a high quality answer? Look at the second paragraph. The answer has been written in a hurry and is of low quality. It could be a comment. It's not a high quality answer. I don't see why it should be upvoted. I don't think upvoting just because an answer was downvoted helps. It just encourages poor answers. I think if Tony came back and saw the downvote he might well improve the answer. Which would be a good thing. – David Heffernan Feb 26 '13 at 17:55
  • @DavidHeffernan, You have a point. I leave that to Tony Hopkinson to improve (as I suggested in my first comment). But I still think that using "TStringList class and it's LoadFromFile method" is a valid answer. – kobik Feb 26 '13 at 17:58
  • @David however downvoting without voicing the reason does not discourage bad answers as well – Arioch 'The Feb 26 '13 at 20:31