PROGRAM CHEM ************************************************************************ * Program to read a file containing the chemical formula, name, and * * specific heat for various inorganic compounds and store these in * * parallel arrays. File is sorted so that the formulas are in * * alphabetical order. The user enters a formula; the list of formulas * * is searched using the binary search algorithm; and if the formula is * * found, its name and specific heat are displayed. Identifiers used * * are: * * LIMIT : parameter specifying maximum # of array elements * * LENGTH : parameter specifying length of character strings * * FORMUL : array of formulas * * NAME : array of names * * SPHEAT : array of specific heats * * N : number of records in the file * * * * Input: Arrays FORMUL, NAME, and SPHEAT (from RDDATA) * * Output: Names and specific heats for certain formulas (by LOOKUP) * ************************************************************************ INTEGER LIMIT, LENGTH, N PARAMETER (LIMIT = 100, LENGTH = 10) CHARACTER*(LENGTH) FORMUL(LIMIT), NAME(LIMIT)*(2*LENGTH) REAL SPHEAT(LIMIT) CALL RDDATA(FORMUL, NAME, SPHEAT, LIMIT, N) CALL LOOKUP(FORMUL, NAME, SPHEAT, LIMIT, N) END **RDDATA**************************************************************** * Subroutine to read a list of up to LIM chemical formulas, names, * * and specific heats, store them in parallel arrays FORMUL, NAME, and * * SPHEAT, and count (N) how many sets of readings are stored. FNAME * * is the name of the file from which data is read and EOF is an * * end-of-file indicator. * * * * Accepts: Arrays FORMUL, NAME, SPHEAT, N (undefined) and * * integer LIM * * Input (keyboard): File name FNAME * * Input (file): Elements of FORMUL, NAME, SPHEAT * * Returns: Arrays FORMUL, NAME, SPHEAT(modified) and integer N* ************************************************************************ SUBROUTINE RDDATA(FORMUL, NAME, SPHEAT, LIM, N) INTEGER LIM, N, EOF CHARACTER*(*) FORMUL(LIM), NAME(LIM) REAL SPHEAT(LIM) CHARACTER*20 FNAME * Open the file, then read, count, and store the items PRINT *, 'ENTER NAME OF FILE' READ '(A)', FNAME OPEN (UNIT = 15, FILE = FNAME, STATUS = 'OLD') N = 1 * While there is more data in the file, read it and * store it in the parallel arrays READ (UNIT = 15, FMT = 100, IOSTAT = EOF) + FORMUL(N), NAME(N), SPHEAT(N) 100 FORMAT(2A, F5.0) 10 IF (EOF .GE. 0) THEN N = N + 1 READ (UNIT = 15, FMT = 100, IOSTAT = EOF) + FORMUL(N), NAME(N), SPHEAT(N) GO TO 10 ELSE N = N - 1 END IF CLOSE(15) END **LOOKUP**************************************************************** * Subroutine that allows user to enter formulas. The array FORMUL * * having N chemical formulas is then searched for this formula, and * * if found, the corresponding elements of the parallel arrays NAME * * and SPHEAT are displayed. User enters QUIT to stop searching. LIM * * dimensions the arrays, and LENGTH is used to specify the lengths of * * the formulas and names. Local identifiers used are: * * UFORM : formula entered by the user * * FOUND : signals if UFORM found in array FORMUL * * LOC : location of UFORM in FORMUL if found * * LENGTH : parameter used to specify length of UFORM * * * * Accepts: Arrays FORMUL, NAME, SPHEAT, and * * integers LIM and N * * Input (keyboard): Several values of UFORM or a 'QUIT' signal * * Output: For each formula that is found, its specific * * heat; otherwise a 'NOT FOUND' message * ************************************************************************ SUBROUTINE LOOKUP(FORMUL, NAME, SPHEAT, LIM, N) INTEGER LIM, N, LOC, LENGTH PARAMETER (LENGTH = 10) CHARACTER*(*) FORMUL(LIM), NAME(LIM) CHARACTER*(LENGTH) UFORM REAL SPHEAT(LIM) LOGICAL FOUND PRINT * PRINT *, 'ENTER FORMULA TO SEARCH FOR, (QUIT TO STOP)' READ '(A)', UFORM * While UFORM not equal to 'QUIT', search FORMUL array for it, * display information found, and read next UFORM 10 IF (UFORM.NE. 'QUIT') THEN CALL BINSCH(FORMUL, LIMIT, N, UFORM, FOUND, LOC) IF (FOUND) THEN PRINT 100, 'HAS SPECIFIC HEAT', SPHEAT(LOC) 100 FORMAT(6X, A, F7.4) ELSE PRINT 100, 'NOT FOUND' END IF PRINT * PRINT *, 'ENTER FORMULA TO SEARCH FOR, (QUIT TO STOP)' READ '(A)', UFORM GO TO 10 END IF END **BINSCH**************************************************************** * Subroutine to search the list ITEM for UITEM using binary search. * * If UITEM is found in the list, FOUND is returned as true and the * * LOCation of the item is returned; otherwise FOUND is false. LIM is * * the limit on the size of ITEM. In this version of binary search, * * UITEM and the elements of ITEM are character strings. Local * * variables used are: * * FIRST : first item in (sub)list being searched * * LAST : last " " " " " * * MIDDLE : middle " " " " " * * * * Accepts: Array ITEM, integers LIM and N, and UITEM * * Returns: If UITEM is found: * * FOUND = true and LOC = its position in the list ITEM * * Otherwise: * * FOUND = false (and LOC = last position examined) * ************************************************************************ SUBROUTINE BINSCH(ITEM, LIM, N, UITEM, FOUND, LOC) INTEGER LIM, N, LOC, FIRST, LAST, MIDDLE CHARACTER*(*) ITEM(LIM), UITEM LOGICAL FOUND FIRST = 1 LAST = N FOUND = .FALSE. * While FIRST less than or equal to LAST and not FOUND do 10 IF ((FIRST .LE. LAST) .AND. .NOT. FOUND) THEN MIDDLE = (FIRST + LAST) / 2 IF (UITEM .LT. ITEM(MIDDLE)) THEN LAST = MIDDLE - 1 ELSE IF (UITEM .GT. ITEM(MIDDLE)) THEN FIRST = MIDDLE + 1 ELSE FOUND = .TRUE. LOC = MIDDLE END IF GO TO 10 END IF END