1

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.
J...
  • 30,968
  • 6
  • 66
  • 143
Filip Sulik
  • 99
  • 1
  • 1
  • 8
  • 4
    Use a dynamic array. I also suggest zero based arrays and that you stop using global vars. – David Heffernan Apr 08 '15 at 21:43
  • Why did you create a [new account](http://stackoverflow.com/users/4732990/filip-sulik) ? – TLama Apr 08 '15 at 21:46
  • http://docwiki.embarcadero.com/RADStudio/XE7/en/Structured_Types#Dynamic_Arrays – Ken White Apr 08 '15 at 21:47
  • 1
    because they wouldnt let me ask no more questions due to my low reputation from asking stupid questions :D @TLama – Filip Sulik Apr 08 '15 at 21:49
  • 2
    What do your instructor and your textbook say about this kind of problem? Check your notes. – Rob Kennedy Apr 09 '15 at 03:46
  • Learning to program means having to suffer through debugging your own code, reading the language documentation / help files, and experimenting with different options. You don't learn much by throwing your hands up in the air after a few minutes, posting the problem to a forum, and asking others to tell you what you seem too lazy to figure out yourself. We've all been there and done that. At the risk of sounding old, I learned to program using punch cards. It took an hour or more to re-compile and run a program. We didn't have any choice but to figure stuff like this out ourselves. – David Schwartz Apr 10 '15 at 10:38

2 Answers2

7

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!

Community
  • 1
  • 1
David
  • 13,360
  • 7
  • 66
  • 130
  • The dynamic array will be freed automatically when it goes out of scope. You don't need to call `SetLength(ArrayName, 0)`. This is true for all managed types (dynarray, strings and interfaces) – Johan Apr 09 '15 at 19:49
  • @Johan For a global variable, though, the scope is the program. And sure, you don't need to free memory when your program exits - but it's good practice. – David Apr 10 '15 at 10:45
0

And if it had not been a school project:

function Comparer(List: TStringList; index1, index2: integer): integer;
begin
  try
    Result:= StrToInt(List[index1]) - StrToInt(List[Index2]);
  except
    raise Exception.Create('Your file does not contain numbers'); 
  end;
end;

function SortNumbers
var
  lStringList: TStringlist;
begin
  lStringList := TStringlist.create;
  try
    lStringList.LoadFromFile('Numbers.txt');
    lStringList.CustomSort(Comparer);
    lStringList.SaveToFile('Sorted-Numbers.txt');
  finally
    lStringList.Free;
  end;
end;

However the Delphi RTL uses Quicksort, not Bubblesort.

Johan
  • 74,508
  • 24
  • 191
  • 319
Hans
  • 2,220
  • 13
  • 33
  • Your exception handling is totally wrong. Returning 0 in that case is not permitted. It allows for nonsense like a=b, a=c and b<>c. – David Heffernan Apr 10 '15 at 05:58