Previous topic | Ada Home Page | Index

Array of Records - Example

Problem Specification

You are to create a system that will record the marks in CS1 for each student in each division at ADFA.

The following items are required

Program design

Data Structure


Code

------------------------------------------------------------------------------
-- Program:  main.a
-- Author:   Chist Lokan
-- Modified: Xin Yao, 10 August 1997
-- Program Purpose: Maintain a database of CS1 marks for ADFA students.
------------------------------------------------------------------------------
with TEXT_IO;

procedure main is

  -- declare integer I/O library
  package int_io is new TEXT_IO.INTEGER_IO(INTEGER);
  use TEXT_IO,int_io;

  -- declare contants
  max_rank_size:    constant:=3;		-- max str length for ranks
  max_sname_size:   constant:=20;		-- max str length of a name
  max_phone_len:    constant:=10;		-- max str length of tel no
  max_div_students: constant:=30;		-- max no of students in a div
  space:            constant CHARACTER := ' ';	-- blank space

  -- declare various types and subtypes
  subtype ranks   is STRING(1..max_rank_size);
  subtype snames  is STRING(1..max_sname_size);
  subtype phones  is STRING(1..max_phone_len);
  type    sexes   is (male, female);
  subtype years   is INTEGER range 1..10;
  subtype results is INTEGER range 1..100;
  
  -- declare and initialise a record type for a student's detail (rank and name)
  type details is record  
    rank: ranks:= (others=> space);          -- rank
    sname: snames:= (others=> space);        -- surname
  end record;

  -- a record type including all information about a student
  type students is record  
    detail: details;				-- rank and name
    phone : phones := (others => space);     -- phone no
    sex   : sexes;				-- sex
    year  : years:=1;				-- year, initialised to 1
    result: results:=1;				-- mark, initialised to 1
  end record;

  -- an array type describing a division of students
  type divresults  is array(1..max_div_students) of students;

  -- an array type describing a number of divisions (unconstrained array)
  type adfaresults is array(INTEGER RANGE <>) of divresults;

  -- deckare an I/O library for the new type sexes
  package sex_io is new TEXT_IO.ENUMERATION_IO (sexes); 
  use sex_io;

  -- declare global variables
  adfaresult : adfaresults(1..6);      		-- ADFA has 6 divs
  c          : character;            		-- a character for reading
  div, 						-- division at ADFA
  pos        : integer;				-- position no
  surname    : snames:= (others=> space);    -- surname of a student
  student    : students;			-- student info (a record)
  nchar      : natural;				-- length of an input string

  --------------------------------------------------------------------------
  -- Function: getstudent
  -- Purpose:  read in all the info about a student and return a record
  --           contain those info
  --------------------------------------------------------------------------
  function getstudent return students is
    student: students;		-- a student record
    nchar:   natural;		-- string length, for GET_LINE

  begin  -- getstudent
    student.detail.rank:=(others=>space);	-- initialise rank to blanks
    PUT("Enter rank: "); 
    GET_LINE(student.detail.rank,nchar);	-- get rank 

    student.detail.sname:=(others=>space);	-- initialise name to blanks
    PUT("Enter surname: ");
    GET_LINE(student.detail.sname,nchar);	-- get surname

    student.phone:=(others=>space);		-- initialise phone no to blanks
    PUT("Enter phone: "); 
    GET_LINE(student.phone,nchar);		-- get phone umber

    PUT("Enter sex: "); 
    GET(student.sex);    SKIP_LINE;		-- get sex
    PUT("Enter year: "); 
    GET(student.year);   SKIP_LINE;		-- get year
    PUT("Enter result: "); 
    GET(student.result); SKIP_LINE;		-- get mark (result)

    return student;
  end getstudent;

  ----------------------------------------------------------------------------
  -- Function: findstudent
  -- Purpose:  find a student with a particular surname in the adfa database
  ----------------------------------------------------------------------------
  function findstudent(adfa:     adfaresults;	-- the student database
		       findname: snames		-- surname to be found
		      ) return students is	-- the student record found
    empty: students;	-- a local variable to hold a student record

  begin  -- findstudent

    for division in adfa'RANGE loop		-- for all the divs at ADFA
      for student in divresults'RANGE loop	-- for all students in a div
        if adfa(division)(student).detail.sname = findname then
	    return adfa(division)(student);	-- found the student
        end if;
      end loop;
    end loop;

    return empty;				-- student not found

  end findstudent;

  ----------------------------------------------------------------------------
  -- Function: averagediv
  -- Purpose:  calculate the average mark of students in a div
  ----------------------------------------------------------------------------
  function averagediv(div: divresults) return INTEGER is
    total:	integer:=0;	-- average mark in a div
    currstud:	integer:=1;	-- index of the array

  begin  -- averagediv

    while ((div(currstud).detail.sname /= "                 ")
                       and (currstud<max_div_students)) loop
      total := total + div(currstud).result;
      currstud := currstud + 1;
    end loop;
    if (currstud-1) = 0 then   -- if no records found, return -1 
      return -1;
    end if;
    return total/(currstud-1);	-- return the average mark as an integer

  end averagediv;


begin  -- main
  loop
   
    -- display the menu
    put_line("What do you want to do");
    put_line("1) Add record");
    put_line("2) Find record");
    put_line("3) Print averages");
    put_line("4) Quit");
    get(c); SKIP_LINE;		-- read in the menu choice

    case (c) is
      when '1' =>           -- add a student record
        put("What div? "); 	-- student's div
	get(div); SKIP_LINE;
        put("What position? "); -- student's sequential position in the div
	get(pos); SKIP_LINE;      
        adfaresult(div)(pos):= getstudent;	-- read in the student info

      when '2' =>           -- find a student record
        put("What surname? "); 
	get_line(surname, nchar);	-- read in the surname
        student := findstudent (adfaresult,surname);	-- find the student
        put(student.result);	-- display his/her mark/result
	NEW_LINE;

      when '3' =>           -- print averages for all divisions
	put_line ("Division   Average Mark");	-- table heading
        for division in adfaresult'RANGE loop
	  put (division, width=>4);		-- display the division number
          put (averagediv(adfaresult(divsision)), width=>14);  
						-- dislpay the average
	  NEW_LINE;
        end loop;

      when others =>	exit;
    end case;

  end loop;
end main;


Previous topic | Ada Home Page | Index
c-lokan@adfa.oz.au / 27 Feb 96