/* ================================================================== Solution by Jiayu Yao This version computes the minimum value Modified by Shun Yan Cheung (+ clean up some code) ================================================================== */ import java.io.*; class DataDescription { String fieldName; String fieldType; int fieldSize; } public class pj1 { static int MAXNFIELDS = 10; // Max. # fields in 1 record static int n_fields; // Actual number of fields /* ------------------------------------------------------------ (1) Variables used to store the DESCRIPTION of the data ------------------------------------------------------------ */ static DataDescription[] dataDes = new DataDescription[MAXNFIELDS]; // This is a CONSTRUCTOR method for static variables static { // Need to create objects for the dataDes[] for ( int i = 0; i < MAXNFIELDS; i++ ) { dataDes[i] = new DataDescription(); } } /* ------------------------------------------------------- (2) Variables used to store the ACTUAL data ------------------------------------------------------- */ static String[] c_buf=new String[MAXNFIELDS]; // Used to store String fields static int[] i_buf=new int[MAXNFIELDS]; // Used to store int fields // TODO: add variable(s) to support double data static double[] d_buf=new double[MAXNFIELDS]; //Used to store double fields public static void main(String[] args) throws IOException { /* =========================================================== We must first find out the STRUCTURE of the data file This information is stored in the data DESCRIPTION file =========================================================== */ DataFile descrFile = new DataFile("db-description"); // 1. Open the data description file /* ------------------------------------------------------- Read in the data description and store them in the DataDes[] array (define in (1)) ------------------------------------------------------- */ n_fields = 0; // Count the actual number of fields in data while ( true ) { try { dataDes[n_fields].fieldName = descrFile.ReadString(24); dataDes[n_fields].fieldType = descrFile.ReadString(4); dataDes[n_fields].fieldSize = descrFile.ReadInt(); System.out.println("Field: " + dataDes[n_fields].fieldName + ", type: " + dataDes[n_fields].fieldType + ", size: " + dataDes[n_fields].fieldSize); n_fields++; } catch ( IOException e ) { System.out.println("\nFinish reading data description file....\n"); break; // Read error: no more data !!! } } DataFile dataFile = new DataFile("db-data"); // First open data file System.out.println( "The data file contains these records:\n"); // TODO: Write a loop to print out the records // You can use the PrintRecord() method below // but you must add support for double in that method while(true) { try { for ( int i = 0; i < n_fields; i++) { /* ------------------------------------------------------ Read in the data depending on the TYPE of this field ------------------------------------------------------ */ if ( dataDes[i].fieldType.equals("I") ) { /* -------------------------------------------------------- Field i is an integer, use i_buf[i] to store the value -------------------------------------------------------- */ i_buf[i] = dataFile.ReadInt(); } else if ( dataDes[i].fieldType.equals("F") ) { /* -------------------------------------------------------- Field i is a double, use d_buf[i] to store the value -------------------------------------------------------- */ d_buf[i] = dataFile.ReadDouble(); } else { /* -------------------------------------------------------- Field i is an String, use c_buf[i] to store the value -------------------------------------------------------- */ c_buf[i] = dataFile.ReadString( dataDes[i].fieldSize ); } } PrintRecord(); } catch ( IOException e ) { System.out.print("Done.\n"); break; } } System.out.print("\nFind min values in the field " + args[0] + "\n"); // TODO: Write a loop to find the minimum value // in the specified fieldName // (which is given in args[0]) // int inputfield = -1; // -1 means: non-existing field // Otherwise, inputfield contains // the index of the field used to // compute the min /* ================================================ Determine the field index that we need to use ================================================ */ for (int i = 0; i < n_fields; i++) { if (dataDes[i].fieldName.equals(args[0])) { inputfield = i; // Remember the intended field break; // Exit search loop - we found the field } } /* ================================================================== Check if the field is valid (non valid --> inputfield contains -1) ================================================================== */ if( inputfield == -1 ) { System.out.println("--- Error: field name not found."); System.exit(1); // Exit program } /* =============================================== Find the min in field with index inputfield =============================================== */ dataFile.rewind(); // Rewind data file /* ====================================== Variables used to compute the min ====================================== */ double min_d = 0; int min_i = 0; String min_s = ""; /* ===================================================== Initialize min using data in the first record ===================================================== */ /* ============================================= Read the first record ============================================= */ for ( int i = 0; i < n_fields; i++) { /* ------------------------------------------------------ Read in the data depending on the TYPE of this field ------------------------------------------------------ */ if ( dataDes[i].fieldType.equals("I") ) { /* ------------------------------------------------------- Field i is an integer, use i_buf[i] to store the value ------------------------------------------------------- */ i_buf[i] = dataFile.ReadInt(); } else if( dataDes[i].fieldType.equals("F")) { /* ------------------------------------------------------- Field i is a double, use d_buf[i] to store the value ------------------------------------------------------- */ d_buf[i] = dataFile.ReadDouble(); } else { /* ----------------------------------------------------- Field i is an String, use c_buf[i] to store the value ------------------------------------------------------ */ c_buf[i] = dataFile.ReadString( dataDes[i].fieldSize ); } } /* ------------------------------------------------------ Find min according the the data type of inputfield ------------------------------------------------------ */ if ( dataDes[inputfield].fieldType.equals("I") ) { /* ------------------------------------------------------- Field i is an integer, use min_i to store the value ------------------------------------------------------- */ min_i = i_buf[inputfield]; } else if( dataDes[inputfield].fieldType.equals("F")) { /* ------------------------------------------------------- Field i is a double, use min_d to store the value ------------------------------------------------------- */ min_d = d_buf[inputfield]; } else { /* ----------------------------------------------------- Field i is an String, use min_s to store the value ------------------------------------------------------ */ min_s = c_buf[inputfield]; } /* ================================================================ Process the other record to find the real min ================================================================ */ while(true) { try { /* ============================================= Read 1 record ============================================= */ for ( int i = 0; i < n_fields; i++) { /* ------------------------------------------------------ Read in the data depending on the TYPE of this field ------------------------------------------------------ */ if ( dataDes[i].fieldType.equals("I") ) { /* ------------------------------------------------------- Field i is an integer, use i_buf[i] to store the value ------------------------------------------------------- */ i_buf[i] = dataFile.ReadInt(); } else if( dataDes[i].fieldType.equals("F")) { /* ------------------------------------------------------- Field i is a double, use d_buf[i] to store the value ------------------------------------------------------- */ d_buf[i] = dataFile.ReadDouble(); } else { /* ----------------------------------------------------- Field i is an String, use c_buf[i] to store the value ------------------------------------------------------ */ c_buf[i] = dataFile.ReadString( dataDes[i].fieldSize ); } } /* =========================================== Find the min value on field "inputfield" =========================================== */ if ( dataDes[inputfield].fieldType.equals("I") ) { if ( i_buf[inputfield] < min_i ) min_i = i_buf[inputfield]; } else if ( dataDes[inputfield].fieldType.equals("F") ) { if ( d_buf[inputfield] < min_d ) min_d = d_buf[inputfield]; } else // Must be a string { if ( c_buf[inputfield].compareTo(min_s) < 0 ) min_s = c_buf[inputfield]; } } catch ( IOException e ) { System.out.print("Done...\n"); break; } } /* ============================================ Print min found ============================================ */ if ( dataDes[inputfield].fieldType.equals("I") ) System.out.println("\nMin = " + min_i); else if ( dataDes[inputfield].fieldType.equals("F") ) System.out.println("\nMin = " + min_d); else System.out.println("\nMin = " + min_s); } public static void PrintRecord() { // TODO: add support to print double data for ( int i = 0; i < n_fields; i++ ) { if ( dataDes[i].fieldType.equals("I") ) { /* -------------------------------------------------------- Field i is an integer, use i_buf[i] to store the value -------------------------------------------------------- */ System.out.print( i_buf[i] + " "); } else if(dataDes[i].fieldType.equals("F")) { /* -------------------------------------------------------- Field i is a double, use d_buf[i] to store the value -------------------------------------------------------- */ System.out.print( d_buf[i] + " "); } else { /* -------------------------------------------------------- Field i is an String, use c_buf[i] to store the value -------------------------------------------------------- */ System.out.print( c_buf[i] + " "); } } System.out.println( ); // Print newline to separate records } }