Search code examples
arraysdelphisortingpascalbubble-sort

Arrays in Delphi (object Pascal) using variables?


I have these 10 numbers (one in each line) in a Text File and I need them to be sorted in a chronological order starting with the highest number. I wrote a code which works just fine, but the problem is that the code isn't flexible, because once I add another number to the Text File it won't work since the code is set to sort 10 numbers only...this is due to my array of integers which is supposed to read the values before the sorting process starts, but won't allow me to add a variable to the array's properties so it will be able to read and sort any-size text file...I know there has to be a way of making a program which can sort any-size file of this structure, just please tell me how I could improve my code. (If you think my way isn't too efficient, it's because that's my homework from high school and I need to use these arrays to implement a bubblesort).

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  numbers, sortednumbers : TextFile;
  count : integer=0;
  number : array[1..10] of integer;
  I : integer;

Procedure Swap(var X, Y : Integer);
  var
  Temp : integer;
  begin
    Temp := X;
    X := Y;
    Y := Temp;
  end;

procedure Assign;
  var I : Integer;
  begin
    reset(numbers);
    for I := 1 to count do ReadLn(numbers, number[I]);
  end;

procedure BubbleSort;
  var I, J : integer;
  begin
    for I := 2 to count do
    begin
     for J := count downto I do
     if (number[J] > number[J - 1]) then
     Swap(number[J - 1], number[J]);
    end;
  end;

begin
  AssignFile(numbers, 'Numbers.txt');
  AssignFile(sortednumbers, 'Sorted-Numbers.txt');
  Reset(numbers);
  While not EoF(numbers) do
    begin
    ReadLn(numbers);
    Inc(count);
    end;
  Reset(numbers);
  ReWrite(sortednumbers);
  Assign;
  BubbleSort;
  For I := 1 to count do writeln(sortednumbers, number[I]);
  CloseFile(numbers);
  CloseFile(sortednumbers);
end.

Solution

  • Use a dynamic array. This is an array that can change the number of elements it holds.

    Instead of declaring:

    number : array[1..10] of integer;
    

    instead skip the bounds declaration:

    Number : array of integer;
    

    Then, before you start using it, set its length:

    SetLength(Number, 10);
    

    Once you are done, free the memory by setting it to have length 0:

    SetLength(Number, 0);
    

    Note that:

    • Indexes of a dynamic array start from 0, not 1. That is, Number[0] is the first element and Number[9] is the tenth. This is quite common in programming but can be confusing if it's not something you've come across before.
    • There are other 'quality' changes you can make to your code too. As commenter David Heffernan said, stop using global variables. I would also suggest using try/finally for resource allocation and cleanup, and using streams (and another link, wrap this over TFileStream) instead of the old-style file IO you're currently doing. Also, consider your variable names - Number for an array of numbers is odd - why not add the S and call it Numbers, for example?

    That might be a bit much all at once, so go slowly in small steps, save and backup often (preferably into source control), and have fun!