Name: Gilroy, Scott EXECUTION TESTS ========= ===== ============================================================ hw2-histogram < hw2-histogram.input1 WELCOME TO HW2-HISTOGRAM!! This program will display a histogram for a list of integers which you provide. You will be asked to enter a sentinel value. This should be some integer which does not occur in the data set, and is used to indicate the end of the data. Then you will enter scores. Once the sentinel value has been entered, you will be asked to provide the upper and lower bounds for the histogram as well as the size of each subinterval. Then the program will generate the desired histogram. Multiple histograms can be displayed for the same data. Enter sentinel value: Now enter values separated by returns and ended with -1. Low value in histogram (-1 to quit): High value in histogram (-1 to quit): Step size: below 2: 2 - 2: 3 - 3: 4 - 4: ** 5 - 5: ** 6 - 6: 7 - 7: ** 8 - 8: * 9 - 9: ** 10 - 10: * 11 - 11: ** above 12: * Low value in histogram (-1 to quit): High value in histogram (-1 to quit): Step size: below 2: 2 - 4: ** 5 - 7: **** 8 - 10: **** 11 - 13: *** above 14: Low value in histogram (-1 to quit): ============================================================ hw2-histogram < hw2-histogram.input2 WELCOME TO HW2-HISTOGRAM!! This program will display a histogram for a list of integers which you provide. You will be asked to enter a sentinel value. This should be some integer which does not occur in the data set, and is used to indicate the end of the data. Then you will enter scores. Once the sentinel value has been entered, you will be asked to provide the upper and lower bounds for the histogram as well as the size of each subinterval. Then the program will generate the desired histogram. Multiple histograms can be displayed for the same data. Enter sentinel value: Now enter values separated by returns and ended with -1. Low value in histogram (-1 to quit): High value in histogram (-1 to quit): Step size: below 2: 2 - 2: * 3 - 3: ** 4 - 4: ********** 5 - 5: ************** 6 - 6: *************** 7 - 7: ***************** 8 - 8: ************** 9 - 9: *********** 10 - 10: ********* 11 - 11: ***** above 12: ** Low value in histogram (-1 to quit): High value in histogram (-1 to quit): Step size: below 4: *** 4 - 5: ************************ 6 - 7: ******************************** 8 - 9: ************************* above 10: **************** Low value in histogram (-1 to quit): ============================================================ hw2-bank < hw2-bank.input1 This program requests several parameters for up to 4 savings plans and then displays a tableshowing the changing balance for each based on interest and payments. For each plan, you must enter: Anual interest rate (in percent per year). Negative means quit. Initial deposit (in dollars and cents). Monthly payment (in dollars and cents). Then you enter the total length of time for collecting interest (in years) for evaluating all of the plans (same time for all). This must be an integer greater than 0. The accumulating balance for each plan (at the beggining of the month) is then calculated and displayed in a table. Each month is shown for the first year, after which only yearly totals are shown. Enter interest rate 1 (negative value to quit): Enter initial amount 1: $Enter payment amount 1: $ Enter interest rate 2 (negative value to quit): Enter initial amount 2: $Enter payment amount 2: $ Enter interest rate 3 (negative value to quit): Enter initial amount 3: $Enter payment amount 3: $ Enter interest rate 4 (negative value to quit): Enter number of years: 1: Init amnt: $1000.00; rate: 10.000000%; payment: $100.00 2: Init amnt: $1000.00; rate: 9.000000%; payment: $100.00 3: Init amnt: $1000.00; rate: 9.000000%; payment: $150.00 Yrs Mos Balance Balance Balance 0 0 1000.00 1000.00 1000.00 0 1 1108.33 1107.50 1157.50 0 2 1217.57 1215.81 1316.18 0 3 1327.72 1324.92 1476.05 0 4 1438.78 1434.86 1637.12 0 5 1550.77 1545.62 1799.40 0 6 1663.69 1657.22 1962.90 0 7 1777.56 1769.64 2127.62 0 8 1892.37 1882.92 2293.58 0 9 2008.14 1997.04 2460.78 0 10 2124.87 2112.02 2629.23 0 11 2242.58 2227.86 2798.95 1 0 2361.27 2344.57 2969.94 2 0 3865.08 3815.26 5124.68 3 0 5526.36 5423.92 7481.55 Enter interest rate 1 (negative value to quit): Enter initial amount 1: $Enter payment amount 1: $Enter number of years: 1: Init amnt: $1000.00; rate: 10.000000%; payment: $100.00 2: Init amnt: $1000.00; rate: 9.000000%; payment: $100.00 3: Init amnt: $1000.00; rate: 9.000000%; payment: $150.00 4: Init amnt: $0.00; rate: -2.000000%; payment: $-158435735510663363533956186112.00 Yrs Mos Balance Balance Balance Balance 0 0 1000.00 1000.00 1000.00 0.00 0 1 1108.33 1107.50 1157.50 -158435735510663363533956186112.00 0 2 1217.57 1215.81 1316.18 -316607415177070587986143346688.00 0 3 1327.72 1324.92 1476.05 -474515473456938097363921141760.00 0 4 1438.78 1434.86 1637.12 -632160344807982315674649231360.00 0 5 1550.77 1545.62 1799.40 -789542501466851529882848985088.00 0 6 1663.69 1657.22 1962.90 -946662359001796232517299208192.00 0 7 1777.56 1769.64 2127.62 -1103520332981066916106778705920.00 0 8 1892.37 1882.92 2293.58 -1260116876751845936137227993088.00 0 9 2008.14 1997.04 2460.78 -1416452443661315648094587584512.00 0 10 2124.87 2112.02 2629.23 -1572527487056658407464797995008.00 0 11 2242.58 2227.86 2798.95 -1728342309169329117905152901120.00 1 0 2361.27 2344.57 2969.94 -1883897514462237586730239655936.00 2 0 3865.08 3815.26 5124.68 -3730460075068771484315322155008.00 Enter number of years: The total time must be greater than 1. ============================================================ hw2-bank < hw2-bank.input2 This program requests several parameters for up to 4 savings plans and then displays a tableshowing the changing balance for each based on interest and payments. For each plan, you must enter: Anual interest rate (in percent per year). Negative means quit. Initial deposit (in dollars and cents). Monthly payment (in dollars and cents). Then you enter the total length of time for collecting interest (in years) for evaluating all of the plans (same time for all). This must be an integer greater than 0. The accumulating balance for each plan (at the beggining of the month) is then calculated and displayed in a table. Each month is shown for the first year, after which only yearly totals are shown. Enter interest rate 1 (negative value to quit): Enter initial amount 1: $Enter payment amount 1: $ Enter interest rate 2 (negative value to quit): Enter initial amount 2: $Enter payment amount 2: $ Enter interest rate 3 (negative value to quit): Enter initial amount 3: $Enter payment amount 3: $ Enter interest rate 4 (negative value to quit): Enter initial amount 4: $Enter payment amount 4: $Enter number of years: 1: Init amnt: $-1000.00; rate: 18.000000%; payment: $10.00 2: Init amnt: $-1000.00; rate: 18.000000%; payment: $20.00 3: Init amnt: $-1000.00; rate: 18.000000%; payment: $30.00 4: Init amnt: $-1000.00; rate: 18.000000%; payment: $40.00 Yrs Mos Balance Balance Balance Balance 0 0 -1000.00 -1000.00 -1000.00 -1000.00 0 1 -1005.00 -995.00 -985.00 -975.00 0 2 -1010.08 -989.92 -969.78 -949.62 0 3 -1015.23 -984.77 -954.32 -923.87 0 4 -1020.45 -979.55 -938.64 -897.73 0 5 -1025.76 -974.24 -922.72 -871.19 0 6 -1031.15 -968.85 -906.56 -844.26 0 7 -1036.61 -963.39 -890.16 -816.93 0 8 -1042.16 -957.84 -873.51 -789.18 0 9 -1047.80 -952.20 -856.61 -761.02 0 10 -1053.51 -946.49 -839.46 -732.43 0 11 -1059.32 -940.68 -822.05 -703.42 1 0 -1065.21 -934.79 -804.38 -673.97 2 0 -1143.17 -856.83 -570.50 -284.16 3 0 -1236.38 -763.62 -290.86 181.90 4 0 -1347.83 -652.17 43.48 739.13 Enter number of years: The total time must be greater than 1. SOURCE FILES ====== ===== #ifndef HW2_UTIL_H #define HW2_UTIL_H #define DEFAULT_ARRAY_CAPACITY 5 /* used to determine the initial size of the array*/ /* * Function: GetDynamicIntArray * Usage: array = GetDynamicIntArray(sentinal, message, &size); * =========================================================================== * This function is useful for getting an array of integers from a user. * The user will be prompted with you message and then can enter an integer. * The user will continue to be prompted until he/she enters a value equal * to your sentinal value. At this point, the function will return a pointer * to the array, and the contents of sizePtr will be set to the size of the array * (the number of integers entered by the user). * The following variables must be sent to the function: * int sentinal: the number to be checked for stopping input * string message: the message displayed as a prompt for entering each integer * int *sizePtr: a pointer to your variable for the size of the array * * Note that the size is not the actual capacity of the array or the amount of * memory allocated. It is the number of integers in the array. */ int *GetDynamicIntArray(int sentinal, string message, int *sizePtr); #endif /* * File: hw2-util.c * Author: Scott Gilroy * Class: CS113 Fall 97 * Assignment: HW2.1 Dynamic Arrays (see Programming Abstractions in C Chapter 2, Exercise 15) * Due Date: 25 September 1997 * Last modified: 25 September 1997 * ----------------------------------------------------- * * USAGE: none (it is a helper function only) * ====== * This will not compile an executable program by itself. * * OVERVIEW: * ========= * This function gets a dynamically sized array of integers from the user. An array is allocated * and the user starts entering values. More memory will be allocated as necessary to allow the * user to enter as many integers as memory will allow. * * Algorithm Notes: * ================ * The process for making more space is as follows * 1. Create new array that is twice the size of the old one * 2. Copy over the old array * Besides this, the program just prompts the user for integers and adds them to the array. * * Known Bugs: none * =========== * * Enhancements: none * ============= * * Error Handling: * =============== * We are carefully with allocating memory by allways checking for a NULL pointer. If NULL is * returned, we stop getting integers from the user and display an error: * printf("Warning! An error occured in GetDynamicIntArray():\n"); * printf("\tCouldn't allocate int array for %d integer(s).\n", newArrayCapacity); * * We then go ahead and return the (valid) array. This is possible because modifications are not * made to the array (or values tracking its size, etc.) untill memory is succesfully allocated. * * Other Comments: * =============== * Note that GetDynamicIntArray could be modified to take any pre-created array to start with and * add to it. To do this, arraySize and arrayCapacity would need to be initialized to *sizePtr * at the beginning, and a pointer to the existing array would need to be passed. * This would assume however that its size and capacity were the same, so we * could end up re-allocating a new array before we actually ran out of space. * Unfortunately, to implement this would require the caller of the function to set *sizePtr * correctly before calling (ie set it to 0 if a new array is desired). Currently, sizePtr can be * set to anything, and the new array will be. * */ #include #include "genlib.h" #include "simpio.h" #include "hw2-util.h" int *GetDynamicIntArray(int sentinal, string message, int *sizePtr) { int * arrayPtr = NULL; /* our dynamicly allocated array */ int * newArrayPtr = NULL; /* used temporarily for copyin over the old array */ int input; /* used to get input */ int arraySize = 0; /* count of integers actually added to the array */ /* For convenience, we'll use arraySize instead of *sizePtr * until we finish (then we'll copy the size to *sizePtr) */ int arrayCapacity = 0; /* allocated space for the array (in num ints) */ int newArrayCapacity = 0; /* max num ints in new array; used for malloc and error reporting */ int i; /* loop variable */ while(TRUE) /* loop forever unless we break out for some reason */ { /* Display a message */ printf("%s", message); /* Get integer from standard input */ fflush(stdin); /* avoid any potential weird errors */ input = GetInteger(); /* Add the integer to the array if input isn't the sentinal number */ if(input == sentinal) { /* we're done; get out */ *sizePtr = arraySize; return arrayPtr; /* we'll return NULL if no valid inputs we're made */ } else { /* see if we need more space for integers */ /* we won't actually change arraySize until the int has been added */ if (arraySize + 1 > arrayCapacity) { /* here's where we do all allocation/deallocation etc. */ /* start by making the new array; figure out size, then malloc */ if(arrayCapacity > 0) newArrayCapacity = arrayCapacity * 2; /* new array will be double the size */ else newArrayCapacity = DEFAULT_ARRAY_CAPACITY; /* if there is no array yet */ newArrayPtr = malloc(sizeof(int) * newArrayCapacity); /* error checking: we won't continue if we couldn't get the space */ if(newArrayPtr == NULL) { /* display error message */ printf("Warning! An error occured in GetDynamicIntArray():\n"); printf("\tCouldn't allocate int array for %d integer(s).\n", newArrayCapacity); /* all variables (arrayPtr, arraySize, arrayCapacity) are all still valid */ *sizePtr = arraySize; return arrayPtr; /* we'll return NULL if no valid inputs we're made */ } /* end if couldn't malloc */ else { /* got a good pointer; copy the old one over */ for(i = 0; i <= arrayCapacity - 1; i++) /* subtract 1 because first element is 0 */ { newArrayPtr[i] = arrayPtr[i]; } /* array has been copied to new array; free the old array */ free(arrayPtr); /* we're done with switching arrays, now point arrayPtr to the new one */ arrayPtr = newArrayPtr; newArrayPtr = NULL; arrayCapacity = newArrayCapacity; newArrayCapacity = 0; /* the transition is complete; the array is the same as the old, */ /* except that now it has twice the space */ } /* end else (got good ptr for new array ) */ } /* end if arrayCapacity is too small */ /* add the newly input integer to the array */ arrayPtr[arraySize] = input; /* arraySize is the empty slot after the last integer */ /* because the first element is 0 so the last */ /* element is arraySize - 1 */ arraySize++; } /* end else, input is valid */ } /* end while(TRUE) */ } /* end GetDynamicIntArray() */ /* ----------- END OF FILE: hw2-util.c ---------- */ #ifndef HW2_STATS_H #define HW2_STATS_H /* * Function: PrintHistogram * Usage: PrintHistogram(scoresArray, size, lo, hi, step); * =========================================================================== * Call this function to display a histogram for an array of integers. * The following must be passed: * scoresArray: array of integers * size: number of integers in the array * lo, hi: the lowest and highest values for making the * subdivisions * step: the size of each subdivision * * Note that hi will not neccessarily be the highest value in the last subdivision. * All subdivisions will be the same size, and the last subdivision will be large * enough to include hi. * The histogram is a bunch of horizontal bars (astrixes) representing the number * of integers in each subdivision. There will be an "above" and "below" group at * the top and bottom for values not in any of the subdivisions. */ void PrintHistogram(int *scoresArray, int size, int lo, int hi, int step); #endif /* * File: hw2-stats.c * Author: Scott Gilroy * Class: CS113 Fall 97 * Assignment: HW 2.2: Histograms (see Programming Abstractions in C Chapter 2, Exercise 6) * Due Date: 25 September 1997 * Last modified: 25 September 1997 * ----------------------------------------------------- * * USAGE: none (it is a helper function only) * ====== * This will not compile an executable program by itself. * * OVERVIEW: * ========= * This function will display a histogram for an array of integers. The histogram will * be displayed with simulated horizontal bars (astrixes) for each range of numbers. * The first line will be the low set containing all numbers less than "lo". Then will * come all of the subdivisions which will be of size step. The subdivisions will go up * to (and including) "hi". Numbers that are not larger than this last subdivision will * be marked in the final line. * * Algorithm Notes: * ================ * First the number of subdivisions is determined so that all numbers between (and including) * lo and hi will fall into a division of size step (see below for details on how this is done). * We then loop through all subdivisions, from the "below" division (values below low) to the * high division. So, we go from -1 to 1 past the number of normal subdivisions to include these * two of the edge cases. The proper message for which line we're on is printed, and then an * astrix is printed for each of the numbers that fall within the current group. This means that * there is some redundancy in computation (each number is checked for each division), but the * code is very simple. * * Known Bugs: none * =========== * * Enhancements: none * ============= * * Error Handling: none * =============== * * Other Comments: * =============== * To improve this algorithm, the array could first be sorted such as below: * * Add to the beginning of main: * /* to reduce computation time and keep the code simple, we will first sort the array * / * qsort(scoresArray, .....) * * /* array is now ordered lowest to hightest; we can now do each line of the histogram * / * * Replace for loop where the astrixes are printed with: * /* print an astrix for each number that is in the division; stop if we go through all * * the ints * / * while((scoresArray[whichInt] <= thisDivisionHigh) && (whichInt < size)) * { * printf("*"); * whichInt++; * } * * Since the integers would be sorted, we could just go until they get to large. * */ #include #include /* needed for qsort function */ #include "genlib.h" #include "simpio.h" #include "hw2-stats.h" void PrintHistogram(int *scoresArray, int size, int lo, int hi, int step) { int numDivisions; /* number of rows needed to have subdivisions of size step */ int whichDivision; /* loop variable; tracks the current subdivision for the histogram */ int whichInt = 0; /* tracks which integer in the array (0,1,2,etc.) we're dealing with*/ int newHigh; /* the new high value, the max of the last subdivision */ int thisDivisionLow; /* lowest value in current subdivision */ int thisDivisionHigh; /* highest value in current subdivision */ /* We want to divide the numbers up into a certain number of divisions. * This might be: (hi - lo) / step * The problem is, what do we do about the remainder? If the range is 10 to 84, and the * step is 10, we would get 7 divisions. Numbers like 83 would get dumped into the hi * catagory. This is not acceptable. We should make an additional subdivision after this * that includes 80 to 89, even though this goes OVER the hi limit. Then, we just make * make the last group everything 90 or bigger. We want an additional group if there * is any remainder from the division. */ if((hi - lo) % step) /* if there is a remainder */ numDivisions = (hi - lo) / step + 1; /* extra subdivision needed */ else /* else it fits perfectly */ numDivisions = (hi - lo) / step; /* no extra needed */ /* subtract 1 from this because otherwise we have the start of the next subdivision */ newHigh = (lo + (numDivisions * step) - 1); /* Loop through each subdivision * Normally we would go from 0 to numDivisions - 1, but we have extra subdivisions at the * beggining (lo) and end (hi). */ for(whichDivision = -1; whichDivision <= numDivisions; whichDivision++) { thisDivisionLow = lo + (whichDivision * step); thisDivisionHigh = lo + (whichDivision * step) + step - 1; /* print the division name */ if(whichDivision == -1) printf("\n below %4d: ", lo); else if(whichDivision == numDivisions) printf("\n above %4d: ", thisDivisionLow); else printf("\n%4d - %4d: ", thisDivisionLow, thisDivisionHigh); /* print an astrix for each number that is in the subdivision */ for(whichInt = 0; whichInt < size; whichInt++) { if ( ((whichDivision == -1) && /* lo division: */ (scoresArray[whichInt] <= thisDivisionHigh)) /* below this high */ || /* OR */ ((scoresArray[whichInt] >= thisDivisionLow) && /* between this low */ (scoresArray[whichInt] <= thisDivisionHigh)) /* and this high */ || /* OR */ ((whichDivision == numDivisions) && /* hi division: */ (scoresArray[whichInt] >= thisDivisionLow)) /* above this low */ ) { printf("*"); } /* end if (integer is in range) */ } /* end for whichInt */ } /* end for whichDivision */ printf("\n\n"); /* make some space at the end */ } /* end printHistogram */ /* ----------- END OF FILE: hw2-stats.c ---------- */ /* * File: hw2-bank.c * Author: Scott Gilroy * Class: CS113, Fall 97 * Assignment: HW 2.3, Savings and Loan: Comparing plans * Due Date: 9/25/97 * Last modified: 9/25/97 * ----------------------------------------------------- * * USAGE: hw2-bank (no commandline arguments) * ====== * * OVERVIEW: * ========= * This program asks the user for several parameters for a each savings plan * (up to 4), as well as the number of years to use, and then displays a table * showing the changing balances for each plan based on interest and payments. * * The values asked for each plan are: * * 1. Interest rate (in percent per year) * A negative interest rate is used as a sentinal to indicate that * there are no more plans. If the first plan has a negative * interest rate, the program will terminate. Otherwise, it will * stop asking for plans and jump to the next part. When the * interest rate is negative, the program will not request * additional inputs. * * 2. Initial deposit (in dollars and cents) * * 3. Monthly payment (in dollars and cents) * * After the last plan (indicated by a negative rate or when four valid * plans have been entered), the user should enter the length of * time (in years). * * A chart is then displayed which shows the balance in the account at the start * (immediately after the initial deposit), at the end of each month in * the first year, and at the end of each year thereafter for each plan. * Also a summary is printed (above the chart) which includes for each plan * the data values entered. * * * Algorithm Notes: * ================ * Uses a basic interest algorith: * interest earned = old balance * anual interest rate / months in a year * new balance = old balance + interest earned + monthly payment * This is done for every month. * * Known Bugs: none * =========== * * Enhancements: none * ============= * * Error Handling: * =============== * 1. Built in error handling from GetReal and GetInteger * * 3. User enters a value less than 1 for time * Message: "The total time must be greater than 1." * Action: Quit. * * Other Comments: * =============== * For best results when viewing this file, the tab size should be set to 4 spaces * * Initially, this program didn't allow negative initial amounts or payments, because * this could cause a negative balance, and negative interest payments, which isn't * exactly how most savings plans work. (interest for dept and for savings is usually * different). The old error checking was as follows: * User enters a negative for initial amount or payment amount * Message: "The initial amount must be greater than 0." * "The payment amount must be greater than 0." * Action: Quit. * * After the initial amount was entered, the following check was made: * * if(planArray[i].initial < 0) /* only 0 and greater allowed * / * { * printf("The initial amount must be greater than 0."); * printf("This is to avoid complications of negative interest."); * exit(0); * } * * After the payment was entered, the following check was made: * * if(planArray[i].payment < 0) /* only 0 and greater allowed * / * { * printf("The payment amount must be greater than 0."); * printf("This is to avoid complications of negative interest."); * exit(0); * } * * */ #include #include #include "genlib.h" #include "simpio.h" /* Constants */ #define MONTHS_PER_YEAR 12 #define MAX_PLANS 4 /* Custom Types */ typedef float moneyT; /* used for currency values (balance, etc.) */ typedef struct { float interest; /* anual interest rate (in percent per year) */ moneyT initial; /* initial deposit (in dollars and cents) */ moneyT payment; /* monthly payment (in dollars and cents) */ } savingsPlanT; /* used to group the savings plan info */ /* Function Prototypes */ void DisplayInstructions(void); moneyT GetMoney(void); void GetValues(int *numPlansPtr, savingsPlanT *planArray, int *totalTimePtr); void DisplayTable(int numPlans, savingsPlanT *planArray, int totalTime); /* Main Program */ int main(void) { int numPlans = 0; savingsPlanT planArray[MAX_PLANS]; int totalTime; /* total length of time for collecting interest */ DisplayInstructions(); while(TRUE) { /* Get all the inputs */ GetValues(&numPlans, planArray, &totalTime); /* we have all we need; show the results */ DisplayTable(numPlans, planArray, totalTime); } /* end while(TRUE) */ /* make some space before exiting */ printf("\n\n"); exit(0); /* let the OS know that the program terminated normally */ } /* end main() */ /* * Function: DisplayInstructions * Usage: DisplayInstructions(); * ----------------------------- * This function prints to standard output instructions for the user. */ void DisplayInstructions() { printf("\nThis program requests several parameters for up to 4 savings plans\n"); printf("and then displays a tableshowing the changing balance for each based\n"); printf("on interest and payments.\n"); printf("For each plan, you must enter:\n"); printf("\tAnual interest rate (in percent per year). Negative means quit.\n"); printf("\tInitial deposit (in dollars and cents).\n"); printf("\tMonthly payment (in dollars and cents).\n"); printf("Then you enter the total length of time for collecting interest (in\n"); printf("years) for evaluating all of the plans (same time for all). This must\n"); printf("be an integer greater than 0.\n\n"); printf("The accumulating balance for each plan (at the beggining of the month)\n"); printf("is then calculated and displayed in a table. Each month is shown for the\n"); printf("first year, after which only yearly totals are shown.\n\n"); } /* end DisplayInstructions() */ /* * Function: GetMoney * Usage: m = GetMoney() * ------------------------------------- * This function will get an amount of money from the user and return a value * of type moneyT. Some basic error handling is done, but any real number is * will be accepted. If desired, a dollar sign should be displayed before this * function is called. */ moneyT GetMoney(void) { /* This function is based heavily on Roberts' GetReal function from the genlib * package. Comments have been added. Some stylistic modifications have been * made. Originally this program required a dollar sign to be entered at the * beggining of the number, but this feature was taken out (although it could easily * be added back in by modifying the sscanf statement). */ string line; /* a sting of user entered text (up to newline character) */ moneyT value; /* the resulting value entered by user and returned */ char termch; /* termination character */ while (TRUE) { line = GetLine(); if (line == NULL) Error("GetMoney: unexpected end of file"); switch (sscanf(line, " %f %c", &value, &termch)) { case 1: /* sscanf worked properly; return value */ FreeBlock(line); return (value); case 2: /* sscanf got a bad character; show error and let user try again */ printf("Unexpected character: '%c'\n", termch); break; default: /* default behavior for other errors from scanf; error and try again */ printf("Please enter an amount (ex: 199.95)\n"); break; } /* end switch */ FreeBlock(line); printf("Retry: "); } /* end while (TRUE) */ } /* end GetMoney() */ /* * Function: GetValues * Usage: GetValues(&numPlans, planArray, &totalTime) * ------------------------------------- * This function will get all the neccessary inputs for up to 4 savings plans, including * interest, initial amount, and payment for each, as well as the total time for * evaluating the balance. */ void GetValues(int *numPlansPtr, savingsPlanT *planArray, int *totalTimePtr) { int i = 0; /* loop variable */ /* loop untill we break out (negative for interest is entered) */ while(*numPlansPtr < MAX_PLANS) { printf("\nEnter interest rate %d (negative value to quit): ", i+1); planArray[i].interest = GetReal(); /* negative means stop entering values */ if (planArray[i].interest < 0) { if(i>0) /* we've got atleast 1 plan entered, break the loop and keep going */ break; else exit(0); /* no plans, exit the program altogether */ } printf("Enter initial amount %d: $", i+1); planArray[i].initial = GetMoney(); printf("Enter payment amount %d: $", i+1); planArray[i].payment = GetMoney(); /* one plan has been entered; increment numPlans */ *numPlansPtr = *numPlansPtr + 1; /* new loop, increment i */ i++; } /* end while(TRUE) */ printf("Enter number of years: "); *totalTimePtr = GetInteger(); if(*totalTimePtr < 1) /* only 1 and greater allowed */ { printf("The total time must be greater than 1."); exit(0); } } /* end GetValues */ /* * Function: DisplayTable * Usage: DisplayTable(numPlans, planArray, totalTime) * ----------------------------- * This function calculates and displays a table with the balances accumulated according * to the initial amounts, yearly interests, monthly payments, and time (in years) for * each plan in planArray. * First the values passed are displayed (initial, interest, payment) for each plan, and * then a table with the columns: years, months, and balance (a balance column will be * shown for each plan). The year, month, and balance (for each plan) is shown * for each month for the starting year, and then just the yearly total thereafter. */ void DisplayTable(int numPlans, savingsPlanT *planArray, int totalTime) { moneyT balance[MAX_PLANS]; /* cummulative balance for each plan */ moneyT interestEarned; /* monthly interest value earned (temporary for calculation) */ int currentYear; /* loop variable tracks the years (starts 0 for this year) */ int currentMonth; /* loop variable tracks the months (starts 0 for this month) */ int i; /* loop variable */ /* initialize all balances */ for(i = 0; i <= numPlans - 1; i++) balance[i] = planArray[i].initial; /* Show the use what will be used for calculations */ for(i = 0; i <= numPlans - 1; i++) { printf("\n%d: Init amnt: $%.2f; rate: %f%%; payment: $%.2f\n", i + 1, planArray[i].initial, planArray[i].interest, planArray[i].payment); } /* Table column names */ printf("\n\nYrs Mos"); for(i = 0; i <= numPlans - 1; i++) { printf(" Balance"); } printf("\n"); /* We will go through every month of every year to calculate the increasing balance. * We step through every month even after the first year (only displaying yearly totals * after the first year) for the sake of conciseness and readability. */ for(currentYear = 0; currentYear <= totalTime; currentYear++) { for(currentMonth = 0; currentMonth <= MONTHS_PER_YEAR - 1; currentMonth++) { /* only print every month for the initial year */ if (currentYear == 0 || currentMonth == 0) { printf("%3d %3d", currentYear, currentMonth); /* print the actual balance of each plan */ for(i = 0; i <= numPlans - 1; i++) printf(" %12.2f", balance[i]); printf("\n"); } /* end if (should print) */ /* do calculations for each plan */ for(i = 0; i <= numPlans - 1; i++) { /* Interest earned is a percentage of the old balance. * The 'interest' is in percent, so we divide by 100 to get the fraction of 1. * The 'interest' is anual interest, so we divide by MONTHS_PER_YEAR. */ interestEarned = balance[i] * (planArray[i].interest / 100) / MONTHS_PER_YEAR; /* new balance is old, plus the interest gained, plus the monthly payment */ balance[i] += interestEarned + planArray[i].payment; } /* next i */ } /* next currentMonth */ } /* next currentYear */ printf("\n\n"); /* make a little space after the table */ } /* end DisplayTable() */ /* ----------- END OF FILE: hw2-bank.c ---------- */ -- END OF LOG FILE FOR sgilroy --