diff --git a/.gitignore b/.gitignore index 40027cb..3a48871 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,11 @@ *.exe PA03-0921/Project_3_PRG PA04-1005/bracketvisualization.txt +PA06-1019/Tax_Report_12022.txt +PA06-1019/Tax_Report_2001.txt +PA06-1019/Tax_Report_2002.txt +PA06-1019/Tax_Report_2003.txt +PA06-1019/Tax_Report_2005.txt +PA06-1019/Tax_Report_2006.txt +PA06-1019/Tax_Report_2010.txt +PA06-1019/Tax_Report_2021.txt diff --git a/PA05-1012/Project_5.c b/PA05-1012/Project_5.c index d3666c1..518ed97 100644 --- a/PA05-1012/Project_5.c +++ b/PA05-1012/Project_5.c @@ -166,8 +166,16 @@ double calculateArizonaTax(double adjustedIncome) // define variables // need a variable that holds the amount of money after the last bracket takes from it. double incomeLeft, totalAZTax; + double maxBaselineTax, maxFirstTax, maxSecondTax; incomeLeft = 0; totalAZTax = 0; + maxBaselineTax = AZ_TAX_BASELINE_LIMIT * AZ_TAX_BASELINE_RATE; + maxFirstTax = maxBaselineTax + + (AZ_TAX_FIRST_BRACKET_LIMIT - AZ_TAX_BASELINE_LIMIT) + * AZ_TAX_FIRST_BRACKET_RATE; + maxSecondTax = maxFirstTax + + (AZ_TAX_SECOND_BRACKET_LIMIT - AZ_TAX_FIRST_BRACKET_LIMIT) + * AZ_TAX_SECOND_BRACKET_RATE; // get input // input is passed in from the function parameter @@ -184,31 +192,22 @@ double calculateArizonaTax(double adjustedIncome) { // check for first bracket and baseline bracket // calculate tax for first and baseline bracket - totalAZTax = AZ_TAX_BASELINE_LIMIT * AZ_TAX_BASELINE_RATE; incomeLeft = adjustedIncome - AZ_TAX_BASELINE_LIMIT; - totalAZTax = totalAZTax + (incomeLeft * AZ_TAX_FIRST_BRACKET_RATE); + totalAZTax = maxBaselineTax + (incomeLeft * AZ_TAX_FIRST_BRACKET_RATE); } else if(adjustedIncome < AZ_TAX_SECOND_BRACKET_LIMIT) { // check for second, first, and baseline bracket // calculate tax for second, first, and baseline bracket - totalAZTax = AZ_TAX_BASELINE_LIMIT * AZ_TAX_BASELINE_RATE; - totalAZTax = totalAZTax + - (AZ_TAX_FIRST_BRACKET_LIMIT * AZ_TAX_FIRST_BRACKET_RATE); incomeLeft = adjustedIncome - AZ_TAX_FIRST_BRACKET_LIMIT; - totalAZTax = totalAZTax + (incomeLeft * AZ_TAX_SECOND_BRACKET_RATE); + totalAZTax = maxFirstTax + (incomeLeft * AZ_TAX_SECOND_BRACKET_RATE); } else { // otherwise, apply the max, second, first, and baseline bracket // calculate tax for max, second, first, and baseline bracket - totalAZTax = AZ_TAX_BASELINE_LIMIT * AZ_TAX_BASELINE_RATE; - totalAZTax = totalAZTax + - (AZ_TAX_FIRST_BRACKET_LIMIT * AZ_TAX_FIRST_BRACKET_RATE); - totalAZTax = totalAZTax + - (AZ_TAX_SECOND_BRACKET_LIMIT * AZ_TAX_SECOND_BRACKET_RATE); incomeLeft = adjustedIncome - AZ_TAX_SECOND_BRACKET_LIMIT; - totalAZTax = totalAZTax + (incomeLeft * AZ_TAX_MAX_RATE); + totalAZTax = maxSecondTax + (incomeLeft * AZ_TAX_MAX_RATE); } // display results @@ -235,8 +234,26 @@ double calculateFederalTax(double adjustedIncome) // need a variable that holds the amount of money after the last bracket takes from it. // as well as a variable to return the amount of tax paid. double incomeLeft, totalFedTax; + double maxBaselineTax, maxFirstTax, maxSecondTax, maxThirdTax, maxFourthTax, + maxFifthTax; incomeLeft = 0; totalFedTax = 0; + maxBaselineTax = FED_TAX_BASELINE_LIMIT * FED_TAX_BASELINE_RATE; + maxFirstTax = maxBaselineTax + + (FED_TAX_FIRST_BRACKET_LIMIT - FED_TAX_BASELINE_LIMIT) + * FED_TAX_FIRST_BRACKET_RATE; + maxSecondTax = maxFirstTax + + (FED_TAX_SECOND_BRACKET_LIMIT - FED_TAX_FIRST_BRACKET_LIMIT) + * FED_TAX_SECOND_BRACKET_RATE; + maxThirdTax = maxSecondTax + + (FED_TAX_THIRD_BRACKET_LIMIT - FED_TAX_SECOND_BRACKET_LIMIT) + * FED_TAX_THIRD_BRACKET_RATE; + maxFourthTax = maxThirdTax + + (FED_TAX_FOURTH_BRACKET_LIMIT - FED_TAX_THIRD_BRACKET_LIMIT) + * FED_TAX_FOURTH_BRACKET_RATE; + maxFifthTax = maxFourthTax + + (FED_TAX_FIFTH_BRACKET_LIMIT - FED_TAX_FOURTH_BRACKET_LIMIT) + * FED_TAX_FIFTH_BRACKET_RATE; // get input // input is passed in from the function parameter @@ -253,64 +270,43 @@ double calculateFederalTax(double adjustedIncome) { // check for first bracket and baseline bracket // calculate tax for first and baseline bracket - totalFedTax = FED_TAX_BASELINE_LIMIT * FED_TAX_BASELINE_RATE; incomeLeft = adjustedIncome - FED_TAX_BASELINE_LIMIT; - totalFedTax = (incomeLeft * FED_TAX_FIRST_BRACKET_RATE) + totalFedTax; + totalFedTax = maxBaselineTax + (incomeLeft * FED_TAX_FIRST_BRACKET_RATE); } else if(adjustedIncome < FED_TAX_SECOND_BRACKET_LIMIT) { // check for second, first, and baseline bracket // calculate tax for second, first, and baseline bracket - totalFedTax = FED_TAX_BASELINE_LIMIT * FED_TAX_BASELINE_RATE; - totalFedTax = totalFedTax + (FED_TAX_FIRST_BRACKET_LIMIT * FED_TAX_FIRST_BRACKET_RATE); incomeLeft = adjustedIncome - FED_TAX_FIRST_BRACKET_LIMIT; - totalFedTax = (incomeLeft * FED_TAX_SECOND_BRACKET_RATE) + totalFedTax; + totalFedTax = maxFirstTax + (incomeLeft * FED_TAX_SECOND_BRACKET_RATE); } else if(adjustedIncome < FED_TAX_THIRD_BRACKET_LIMIT) { // check for third, second, first, and baseline bracket // calculate tax for third, second, first, and baseline bracket - totalFedTax = FED_TAX_BASELINE_LIMIT * FED_TAX_BASELINE_RATE; - totalFedTax = totalFedTax + (FED_TAX_FIRST_BRACKET_LIMIT * FED_TAX_FIRST_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_SECOND_BRACKET_LIMIT * FED_TAX_SECOND_BRACKET_RATE); incomeLeft = adjustedIncome - FED_TAX_SECOND_BRACKET_LIMIT; - totalFedTax = (incomeLeft * FED_TAX_THIRD_BRACKET_RATE) + totalFedTax; + totalFedTax = maxSecondTax + (incomeLeft * FED_TAX_THIRD_BRACKET_RATE); } else if(adjustedIncome < FED_TAX_FOURTH_BRACKET_LIMIT) { // check for fourth, third, second, first, and baseline bracket // calculate tax for fourth, third, second, first, and baseline bracket - totalFedTax = FED_TAX_BASELINE_LIMIT * FED_TAX_BASELINE_RATE; - totalFedTax = totalFedTax + (FED_TAX_FIRST_BRACKET_LIMIT * FED_TAX_FIRST_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_SECOND_BRACKET_LIMIT * FED_TAX_SECOND_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_THIRD_BRACKET_LIMIT * FED_TAX_THIRD_BRACKET_RATE); incomeLeft = adjustedIncome - FED_TAX_THIRD_BRACKET_LIMIT; - totalFedTax = (incomeLeft * FED_TAX_FOURTH_BRACKET_RATE) + totalFedTax; + totalFedTax = maxThirdTax + (incomeLeft * FED_TAX_FOURTH_BRACKET_RATE); } else if(adjustedIncome < FED_TAX_FIFTH_BRACKET_LIMIT) { // check for fifth, fourth, third, second, first, and baseline bracket // calculate tax for fifth, fourth, third, second, first, and baseline bracket - totalFedTax = FED_TAX_BASELINE_LIMIT * FED_TAX_BASELINE_RATE; - totalFedTax = totalFedTax + (FED_TAX_FIRST_BRACKET_LIMIT * FED_TAX_FIRST_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_SECOND_BRACKET_LIMIT * FED_TAX_SECOND_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_THIRD_BRACKET_LIMIT * FED_TAX_THIRD_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_FOURTH_BRACKET_LIMIT * FED_TAX_FOURTH_BRACKET_RATE); incomeLeft = adjustedIncome - FED_TAX_FOURTH_BRACKET_LIMIT; - totalFedTax = (incomeLeft * FED_TAX_FIFTH_BRACKET_RATE) + totalFedTax; + totalFedTax = maxFourthTax + (incomeLeft * FED_TAX_FIFTH_BRACKET_RATE); } else { // otherwise, apply the max, fifth, fourth, third, second, first, and baseline bracket // calculate tax for max, fifth, fourth, third, second, first, and baseline bracket - totalFedTax = FED_TAX_BASELINE_LIMIT * FED_TAX_BASELINE_RATE; - totalFedTax = totalFedTax + (FED_TAX_FIRST_BRACKET_LIMIT * FED_TAX_FIRST_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_SECOND_BRACKET_LIMIT * FED_TAX_SECOND_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_THIRD_BRACKET_LIMIT * FED_TAX_THIRD_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_FOURTH_BRACKET_LIMIT * FED_TAX_FOURTH_BRACKET_RATE); - totalFedTax = totalFedTax + (FED_TAX_FIFTH_BRACKET_LIMIT * FED_TAX_FIFTH_BRACKET_RATE); incomeLeft = adjustedIncome - FED_TAX_FIFTH_BRACKET_LIMIT; - totalFedTax = (incomeLeft * FED_TAX_MAX_RATE) + totalFedTax; + totalFedTax = maxFifthTax + (incomeLeft * FED_TAX_MAX_RATE); } // display results diff --git a/PA06-1019/Arizona_Tax_Utility.c b/PA06-1019/Arizona_Tax_Utility.c new file mode 100644 index 0000000..37133b9 --- /dev/null +++ b/PA06-1019/Arizona_Tax_Utility.c @@ -0,0 +1,70 @@ +// header file +#include "Arizona_Tax_Utility.h" + +// Defined Functions: +/* +Name: calculateArizonaTax +Process: calculates total marginal Arizona tax based on adjusted income +Function Input/Parameters: adjustedIncome +Function Output/Parameters: none +Function Output/Returned: totalAZTax +Device Input/Keyboard: none +Device Output/Monitor: none +Dependencies: none +*/ +double calculateArizonaTax(double adjustedIncome) +{ + // define variables + // need a variable that holds the amount of money after the last bracket takes from it. + double incomeLeft, totalAZTax; + double maxBaselineTax, maxFirstTax, maxSecondTax; + incomeLeft = 0; + totalAZTax = 0; + maxBaselineTax = AZ_TAX_BASELINE_LIMIT * AZ_TAX_BASELINE_RATE; + maxFirstTax = maxBaselineTax + + (AZ_TAX_FIRST_BRACKET_LIMIT - AZ_TAX_BASELINE_LIMIT) + * AZ_TAX_FIRST_BRACKET_RATE; + maxSecondTax = maxFirstTax + + (AZ_TAX_SECOND_BRACKET_LIMIT - AZ_TAX_FIRST_BRACKET_LIMIT) + * AZ_TAX_SECOND_BRACKET_RATE; + + // get input + // input is passed in from the function parameter + + // do calculations + // use if statements to calculate through the progressive tax brackets + if (adjustedIncome < AZ_TAX_BASELINE_LIMIT) + { + // check for baseline bracket + // calculate tax for baseline + totalAZTax = adjustedIncome * AZ_TAX_BASELINE_RATE; + } + else if(adjustedIncome < AZ_TAX_FIRST_BRACKET_LIMIT) + { + // check for first bracket and baseline bracket + // calculate tax for first and baseline bracket + incomeLeft = adjustedIncome - AZ_TAX_BASELINE_LIMIT; + totalAZTax = maxBaselineTax + (incomeLeft * AZ_TAX_FIRST_BRACKET_RATE); + } + else if(adjustedIncome < AZ_TAX_SECOND_BRACKET_LIMIT) + { + // check for second, first, and baseline bracket + // calculate tax for second, first, and baseline bracket + incomeLeft = adjustedIncome - AZ_TAX_FIRST_BRACKET_LIMIT; + totalAZTax = maxFirstTax + (incomeLeft * AZ_TAX_SECOND_BRACKET_RATE); + } + else + { + // otherwise, apply the max, second, first, and baseline bracket + // calculate tax for max, second, first, and baseline bracket + incomeLeft = adjustedIncome - AZ_TAX_SECOND_BRACKET_LIMIT; + totalAZTax = maxSecondTax + (incomeLeft * AZ_TAX_MAX_RATE); + } + + // display results + // not needed, returns instead. + + // return value + // returns the final calculated tax + return totalAZTax; +} diff --git a/PA06-1019/Arizona_Tax_Utility.h b/PA06-1019/Arizona_Tax_Utility.h new file mode 100644 index 0000000..6685fd9 --- /dev/null +++ b/PA06-1019/Arizona_Tax_Utility.h @@ -0,0 +1,50 @@ +// Creation of Arizona_Tax_Utility.h +#ifndef ARIZONA_TAX_UTILITY_H +#define ARIZONA_TAX_UTILITY_H + +// Header Files +#include +#include +#include +#include "StandardConstants.h" + +// Global Constants +// AZ taxes + // AZ tax Baseline RATE +//static const double AZ_TAX_BASELINE_RATE = 0.0259; +#define AZ_TAX_BASELINE_RATE 0.0259 + // AZ tax Baseline LIMIT +//static const double AZ_TAX_BASELINE_LIMIT = 27808.5; +#define AZ_TAX_BASELINE_LIMIT 27808.5 + // AZ tax First bracket RATE +//static const double AZ_TAX_FIRST_BRACKET_RATE = 0.0334; +#define AZ_TAX_FIRST_BRACKET_RATE 0.0334 + // AZ tax First bracket LIMIT +//static const double AZ_TAX_FIRST_BRACKET_LIMIT = 55615.5; +#define AZ_TAX_FIRST_BRACKET_LIMIT 55615.5 + // AZ tax Second bracket RATE +//static const double AZ_TAX_SECOND_BRACKET_RATE = 0.0417; +#define AZ_TAX_SECOND_BRACKET_RATE 0.0417 + // AZ tax Second bracket LIMIT +//static const double AZ_TAX_SECOND_BRACKET_LIMIT = 166843.5; +#define AZ_TAX_SECOND_BRACKET_LIMIT 166843.5 + // AZ tax MAX bracket RATE +//static const double AZ_TAX_MAX_RATE = 0.045; +#define AZ_TAX_MAX_RATE 0.045 + +// Function Prototypes + +/* +Name: calculateArizonaTax +Process: Calculates Arizona Tax +Function input/parameters: adjustedIncome +Function output/parameters: none +Function output/returned: totalAZTax +Device input/keyboard: none +Device output/monitor: none +Dependencies: none +*/ +double calculateArizonaTax(double adjustedIncome); + +// end Arizona_Tax_Utility.h +#endif diff --git a/PA06-1019/Console_IO_Utility.c b/PA06-1019/Console_IO_Utility.c new file mode 100644 index 0000000..38b9f46 --- /dev/null +++ b/PA06-1019/Console_IO_Utility.c @@ -0,0 +1,590 @@ +// Header files included +#include "Console_IO_Utility.h" + +// Function Implementations + +/* +Name: clearLeadingCharacters +Process: Clears all leading non-printable characters from the console stream +Function input/parameters: allow space return (Boolean) +Function output/parameters: none +Function output/returned: first printable character as integer +Device input/keyboard: none +Device output/monitor: none +Dependencies: getchar +*/ +int clearLeadingCharacters( bool allowSpaceReturn ) + { + // initialize data, set input character to getChar, set count to zero + // function: getchar + int intChar = getchar(); + int charCount = 0; + + // loop while non-printable characters and space if not set + // also limits looping to constant limit + while( ( intChar < (int)SPACE + || ( !allowSpaceReturn && intChar == SPACE ) ) + && charCount < MAX_STR_LEN ) + { + // update character count + charCount++; + + // get new input character + // function: getchar + intChar = getchar(); + } + + // return captured character + return intChar; + } + +/* + +Name: getChar +Process: returns next character in stream, + ignores all white space (including SPACE) prior to character +Function input/parameters: flag to accept space (Boolean) +Function output/parameters: none +Function output/returned: one character (char) is returned to calling method +Device input/keyboard: places one or more characters in stream +Device output/monitor: none +Dependencies: getCharFiltered +*/ +char getChar() + { + // initialize variables, set space accept flag to false + bool dontAcceptSpace = false; + + // call filtered function with space accept flag + // function: getCharFiltered + return getCharFiltered( dontAcceptSpace ); + } + +/* +Name: getCharFiltered +Process: returns next character in stream, + ignores non printable characters prior to input character + but may accept space depending on flag +Function input/parameters: flag to accept space (boolean) +Function output/parameters: none +Function output/returned: first printable character or space (if configured) + returned (char) +Device input/keyboard: places one or more characters in stream +Device output/monitor: none +Dependencies: getchar(), clearLeadingCharacters +*/ +char getCharFiltered( bool acceptSpace ) + { + //Initialize variables + int inCharInt; + + // clear leading characters, capture first usable character + // function: clearLeadingCharacters + inCharInt = clearLeadingCharacters( acceptSpace ); + + // check for input character set to end of file + if( inCharInt == EOF ) + { + // return character zero + return '0'; + } + + // return input character as character + return (char)inCharInt; + } + +/* +Name: getInputString +Process: acquires input string from keyboard, if clear white space flag set, + ignores all white space, including space character +Function input/parameters: clear white space control (Boolean) +Function output/parameters: character array (char[]) +Function output/returned: none +Device input/keyboard: user entry of a character stream +Device output/monitor: none +Dependencies: getchar(), clearLeadingCharacters +*/ +void getInputString( char inputArr[], bool clearWhiteSpace ) + { + //Initialize Variables, set character count and index to zero + int charCount = 0; + int index = 0; + int intChar; + + // check for clear white space flag + if( clearWhiteSpace ) + { + // clear leading characters, set flag to ignore space + // function: clearLeadingCharacters + intChar = clearLeadingCharacters( !clearWhiteSpace ); + } + + // otherwise, assume white space flag not set + else + { + // get first character + // function: getchar + intChar = getChar(); + } + + // loop until enter key found, limit loop to constant + while( intChar != (int)NEWLINE_CHAR && charCount < MAX_STR_LEN ) + { + // set current value to array element + inputArr[ index ] = (char)intChar; + + // increment string array index + index++; + + // add null character to end of string array + inputArr[ index ] = NULL_CHAR; + + // increment character count + charCount++; + + // get next character + // function: getchar + intChar = getchar(); + } + } + +/* +Name: printCharacter +Process: prints a single character +Function input/parameters: character to be printed (char) +Function output/parameters: None +Function output/returned: None +Device input/keyboard: None +Device output/monitor: character printed as specified +Dependencies: printCharacters +*/ +void printCharacter( char outputChar ) + { + // initialize number of characters to one + int numberOfChars = 1; + + // print one character + // function: printChars + printCharacters( numberOfChars, outputChar ); + } + +/* +Name: printCharacters +Process: prints given number of characters +Function input/parameters: number of characters (int), + character to be printed (char) +Function output/parameters: None +Function output/returned: None +Device input/keyboard: None +Device output/monitor: Number of specified characters printed +Dependencies: printf +*/ +void printCharacters( int numChars, char outputChar ) + { + // check for reminaing characters to print + if( numChars > 0 ) + { + // print one character + // function: printf + printf( "%c", outputChar ); + + // (recursive) print remaining characters + // function: printChars + printCharacters( numChars - 1, outputChar ); + } + } + +/* +Name: printDouble +Process: simple print double function +Function input/parameters: + outVal - the double value to be output (double) + precision - the number of digits to the right of the decimal point (int) +Function output/parameters: none +Function output/returned: none +Device input: none +Device output/monitor: one double value displayed +Dependencies: printDoubleJustified +*/ +void printDouble( double outVal, int precision ) + { + // initialize variables, set block size to zero and justified to "LEFT" + int blockSize = 0; + char justified[] = "LEFT"; + + // call justified function with specified parameters + // function: printDoubleJustified + printDoubleJustified( outVal, precision, blockSize, justified ); + } + +/* +Name: printDoubleJustified +Process: the precision is set for the double value, then the pre-spaces + and post-spaces are calculated for the requested justification, + and then the pre-spaces are printed, the double value is printed, + and then the post-spaces are printed +Function input/parameters: + outVal - the double value to be output (double) + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification in block (c-string) +Function output/parameters: none +Function output/returned: none +Device input: none +Device output/monitor: one double value displayed, justified, with precision +Dependencies: formatDouble, printStringJustified +*/ +void printDoubleJustified( double outVal, int precision, + int blockSize, const char* justify ) + { + // initialize variables, create temp string for configuration string + char specStr[ MIN_STR_LEN ]; + + // initialize variables, create temporary output string + char outStr[ MIN_STR_LEN ]; + + // set configuration string with precision value + // function: sprintf + sprintf( specStr, "%s0.%dlf", "%", precision ); + + // set output string + // function: sprintf + sprintf( outStr, specStr, outVal ); + + // print string justified + // function: printStringJustified + printStringJustified( outStr, blockSize, justify ); + } + +/* +Name: printEndline +Process: prints single endline character to end a line or create vertical space +Function input/parameters: none +Function output/parameters: none +Function output/returned: none +Device input: none +Device output/monitor: one endline character output +Dependencies: printf +*/ +void printEndline() + { + // print one newline character + // function: printf + printf( "\n" ); + } + +/* +Name: printEndlines +Process: prints the specified number of endline characters + to end a line and/or create vertical space(s) +Function input/parameters: number of endlines (int) +Function output/parameters: none +Function output/returned: none +Device input: none +Device output/monitor: endline characters output as specified +Dependencies: printEndline +*/ +void printEndlines( int numEndlines ) + { + // check for number of end lines remaining + if( numEndlines > 0 ) + { + // print one endling + // function: printEndline + printEndline(); + + // (recursive) print remaining end lines + printEndlines( numEndlines - 1 ); + } + } + +/* + Name: printInteger + Process: prints integer value +Function input/parameters: outVal - the integer value to be output + Output: None + Device Input: None + Device Output: Integer is displayed as specified + Dependencies: printIntegerJustified + */ +void printInteger( int outVal ) + { + // initialize variables, set block size to zero, justifification to "LEFT" + int blockSize = 0; + char justified[] = "LEFT"; + + // print justified integer with specified parameters + // function: printIntegerJustified + printIntegerJustified( outVal, blockSize, justified ); + } + +/* + Name: printIntegerJustified + Process: prints integer value with the specified justification + within the specified blockSize +Function input/parameters: + outVal - the integer value to be output + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification in block (c-string) + Output: None + Device Input: None + Device Output: Integer is displayed as specified + Dependencies: sprintf, printStringJustified + */ +void printIntegerJustified( int outVal, int blockSize, const char *justify ) + { + // initialize variables, create temporary output string + char outStr[ MIN_STR_LEN ]; + + // convert integer to string + // function: sprintf + sprintf( outStr, "%d", outVal ); + + // print justified string + // function: printStringJustified + printStringJustified( outStr, blockSize, justify ); + } + +/* +Name: printLongInteger +Process: prints long integer +Function input/Parameters: outVal - the long integer value to be output +Function output/parameters: None +Function output/returned: None +Device Input/keyboard: None +Device Output/Monitor: integer is displayed as specified +Dependencies: printLongIntJustified +*/ +void printLongInteger( long outVal ) + { + // initialize variables, set block size to zero, justification to "LEFT" + int blockSize = 0; + char justified[] = "LEFT"; + + // print justified long integer with specified parameters + // function: printLongIntegerJustified + printLongIntegerJustified( outVal, blockSize, justified ); + } + +/* +Name: printLongIntegerJustified +Process: prints long integer with the specified justification + within the specified blockSize +Function input/Parameters: + outVal - the long integer value to be output + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification in block (c-string) +Function output/parameters: None +Function output/returned: None +Device Input/keyboard: None +Device Output/Monitor: integer is displayed as specified +Dependencies: sprintf, printStringJustified +*/ +void printLongIntegerJustified( long outVal, + int blockSize, const char *justify ) + { + // initialize variables, create temporary output string + char outStr[ MIN_STR_LEN ]; + + // convert long integer to string + // function: sprintf + sprintf( outStr, "%ld", outVal ); + + // print justified string + // function: printStringJustified + printStringJustified( outStr, blockSize, justify ); + } + +/* + Name: printString + Process: prints string +Function input/parameters: outVal - the string value to be output +Function output/parameters: None +Function output/returned: None +Function input/keyboard: None +Device output/monitor: string is displayed as specified +Dependencies: printStringJustified +*/ +void printString( const char *outStr ) + { + // initialize variables, set block size to zero, justification to "LEFT" + int blockSize = 0; + char justified[] = "LEFT"; + + // print justified string with specified parameters + // function: printStringJustified + printStringJustified( outStr, blockSize, justified ); + } + +/* + Name: printStringJustified + Process: prints string within specified block size + and with specified justification +Function input/parameters: + outVal - the string value to be output + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification in block (c-string) +Function output/parameters: None +Function output/returned: None +Function input/keyboard: None +Device output/monitor: string is displayed as specified +Dependencies: strlen, strcmp, printCharacters, printf +*/ +void printStringJustified ( const char *outStr, + int blockSize, const char *justify ) + { + // initialize variables, set pre-, post- spaces to zero + int preSpaces = 0, postSpaces = 0, strLength; + + // find length of string + // function: strlen + strLength = strlen( outStr ); + + // check justification for "LEFT" + // function: strcmp + if( strcmp( justify, "LEFT" ) == 0 ) + { + // set post spaces for left justification + postSpaces = blockSize - strLength; + } + + // otherwise, check justification for "RIGHT" + // function: strcmp + else if( strcmp( justify, "RIGHT" ) == 0 ) + { + // set pre spaces for right justification + preSpaces = blockSize - strLength; + } + + // Otherwise, assume "CENTER" justification + else + { + // set pre spaces for centered + preSpaces = blockSize / 2 - strLength / 2; + + // set post spaces for centered + postSpaces = blockSize - strLength - preSpaces; + } + + // print pre spaces + // function: printChars + printCharacters( preSpaces, SPACE ); + + // print string + // function: printf + printf( "%s", outStr ); + + // print post spaces + // function: printChars + printCharacters( postSpaces, SPACE ); + } + +/* +Name: promptForCharacter +Process: prompts user for character, then returns it +Function input/parameters: text to prompt user (c-string) +Function output/parameters: None +Function output/returned: one character (chars +Device input/keyboard: user entry of a character +Device output/monitor: prompt string displayed +Dependencies: printf, getChar +*/ +char promptForCharacter( const char *promptString ) + { + // initialize variables + char outChar; + + // print prompt string + // function: printf + printf( "%s", promptString ); + + // get character from stream + // function: getChar + outChar = (char)getChar(); + + // return captured character + return outChar; + } + +/* +Name: promptForDouble +Process: prompts user for double, then returns it +Function input/parameters: test to prompt user (c-string) +Function output/parameters: None +Function output/returned: value (double) +Device input/keyboard: user entry of an integer value +Device output/monitor: prompt string displayed +Dependencies: printf, scanf + */ +double promptForDouble( const char *promptString ) + { + // initialize variables + double outDouble; + + // print prompt string + // function: printf + printf( "%s", promptString ); + + // get double value + // function: scanf + scanf( "%lf", &outDouble ); + + // return captured double + return outDouble; + } + +/* +Name: promptForInteger +Process: prompts user for integer, then returns it +Function input/parameters: text to prompt user (c-string) +Function output/parameters: none +Function output/returned: integer value (int) +Device input/keyboard: user entry of a double value +Device output/monitor: prompt string displayed +Dependencies: printf, scanf +*/ +int promptForInteger( const char *promptString ) + { + // initialize variables + int outInt; + + // print prompt string + // function: printf + printf( "%s", promptString ); + + // input integer + // function: scanf + scanf( "%d", &outInt ); + + // return captured integer + return outInt; + } + +/* +Name: promptForString +Process: prompts user for string, then returns it +Function input/parameters: text to prompt user (c-string) +Function output/parameters: input string from user(c-string) +Function output/returned: none +Device input/keyboard: user entry of a string value +Device output/monitor: prompt string displayed +Dependencies: printf, getInputString +*/ +void promptForString( const char *promptString, char returnStr[] ) + { + // initialize variables, don't allow white space capture + bool dontClearWhitespace = false; + + // pring prompt string + // function: printf + printf( "%s", promptString ); + + // get input string from user (returned via parameter) + // function: getInputString + getInputString( returnStr, dontClearWhitespace ); + } + + diff --git a/PA06-1019/Console_IO_Utility.h b/PA06-1019/Console_IO_Utility.h new file mode 100644 index 0000000..23bb672 --- /dev/null +++ b/PA06-1019/Console_IO_Utility.h @@ -0,0 +1,289 @@ +// Preprocessor directive +#ifndef CONSOLE_IO_UTILITY_H +#define CONSOLE_IO_UTILITY_H + +//Header Files +#include +#include +#include +#include "StandardConstants.h" + +//Global Constants + + // none + +//Function Prototypes + +/* +Name: clearLeadingCharacters +Process: Clears all leading non-printable characters from the console stream +Function input/parameters: allow space return (bool) +Function output/parameters: none +Function output/returned: first printable character as integer +Device input/keyboard: none +Device output/monitor: none +Dependencies: getchar +*/ +int clearLeadingCharacters( bool allowSpaceReturn ); + +/* +Name: getChar +Process: returns next character in stream, + ignores all white space (including SPACE) prior to character +Function input/parameters: flag to accept space (bool) +Function output/parameters: none +Function output/returned: one character (char) is returned to calling method +Device input/keyboard: places one or more characters in stream +Device output/monitor: none +Dependencies: +*/ +char getChar(); + +/* +Name: getCharFiltered +Process: returns next character in stream, + ignores non printable characters prior to input character + but may accept space depending on flag +Function input/parameters: flag to accept space (bool) +Function output/parameters: none +Function output/returned: first printable character or space (if configured) + returned (char) +Device input/keyboard: places one or more characters in stream +Device output/monitor: none +Dependencies: getchar(), clearLeadingCharacters +*/ +char getCharFiltered( bool acceptSpace ); + +/* +Name: getInputString +Process: acquires input string from keyboard, if clear white space flag set, + ignores all white space, including space character +Function input/parameters: clear white space control (bool) +Function output/parameters: character array (char[]) +Function output/returned: none +Device input/keyboard: user entry of a character stream +Device output/monitor: none +Dependencies: getchar(), clearLeadingCharacters +*/ +void getInputString(char inputArr[], bool clearWhiteSpace ); + +/* +Name: printCharacter +Process: prints a single character +Function input/parameters: character to be printed (char) +Function output/parameters: None +Function output/returned: None +Device input/keyboard: None +Device output/monitor: character printed as specified +Dependencies: printCharacters +*/ +void printCharacter( char outputChar ); + +/* +Name: printCharacters +Process: prints given number of characters +Function input/parameters: number of characters (int), + character to be printed (char) +Function output/parameters: None +Function output/returned: None +Device input/keyboard: None +Device output/monitor: Number of specified characters printed +Dependencies: printf +*/ +void printCharacters( int numChars, char outputChar ); + +/* +Name: printDouble +Process: simple print double function +Function input/parameters: + outVal - the double value to be output (double) + precision - the number of digits to the right of the decimal point (int) +Function output/parameters: none +Function output/returned: none +Device input: none +Device output/monitor: one double value displayed +Dependencies: printDoubleJustified +*/ +void printDouble( double outVal, int precision ); + +/* +Name: printDoubleJustified +Process: the precision is set for the double value, then the pre-spaces + and post-spaces are calculated for the requested justification, + and then the pre-spaces are printed, the double value is printed, + and then the post-spaces are printed +Function input/parameters: + outVal - the double value to be output (double) + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification in block (c-string) +Function output/parameters: none +Function output/returned: none +Device input: none +Device output/monitor: one double value displayed, justified, with precision +Dependencies: formatDouble, printStringJustified +*/ +void printDoubleJustified( double outVal, int precision, + int blockSize, const char* justify ); + +/* +Name: printEndline +Process: prints single endline character to end a line or create vertical space +Function input/parameters: none +Function output/parameters: none +Function output/returned: none +Device input: none +Device output/monitor: one endline character output +Dependencies: printEndline +*/ +void printEndline(); + +/* +Name: printEndlines +Process: prints the specified number of endline characters + to end a line and/or create vertical space(s) +Function input/parameters: number of endlines (int) +Function output/parameters: none +Function output/returned: none +Device input: none +Device output/monitor: endline characters output as specified +Dependencies: printEndline +*/ +void printEndlines( int numEndlines ); + +/* + Name: printInteger + Process: prints integer value +Function input/parameters: outVal - the integer value to be output + Output: None + Device Input: None + Device Output: Integer is displayed as specified + Dependencies: printIntegerJustified + */ +void printInteger( int outVal ); + +/* + Name: printIntegerJustified + Process: prints integer value with the specified justification + within the specified blockSize +Function output/parameters: + outVal - the integer value to be output (int) + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification in block (c-string) + Output: None + Device Input: None + Device Output: Integer is displayed as specified + Dependencies: sprintf, printStringJustified + */ +void printIntegerJustified( int outVal, int blockSize, const char *justify ); + +/* +Name: printLongInteger +Process: prints long integer +Function input/Parameters: outVal - the long integer value to be output +Function output/parameters: None +Function output/returned: None +Device Input/keyboard: None +Device Output/Monitor: integer is displayed as specified +Dependencies: printLongIntJustified +*/ +void printLongInteger( long outVal ); + +/* +Name: printLongIntegerJustified +Process: prints long integer with the specified justification + within the specified blockSize +Function Input/Parameters: + outVal - the long integer value to be output (long int) + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification in block (c-string) +Function output/parameters: None +Function output/returned: None +Device Input/keyboard: None +Device Output/Monitor: integer is displayed as specified +Dependencies: sprintf, printStringJustified +*/ +void printLongIntegerJustified( long outVal, + int blockSize, const char *justify ); + +/* + Name: printString + Process: prints string +Function input/parameters: outVal - the string value to be output +Function output/parameters: None +Function output/returned: None +Function input/keyboard: None +Device output/monitor: string is displayed as specified +Dependencies: printStringJustified +*/ +void printString( const char *outStr ); + +/* + Name: printStringJustified + Process: prints string within specified block size + and with specified justification +Function input/parameters: + outVal - the string value to be output (c-string) + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification in block (c-string) +Function output/parameters: None +Function output/returned: None +Function input/keyboard: None +Device output/monitor: string is displayed as specified +Dependencies: strlen, strcmp, printCharacters, printf +*/ +void printStringJustified( const char *outStr, + int blockSize, const char *justify ); + +/* +Name: promptForCharacter +Process: prompts user for character, then returns it +Function input/parameters: text to prompt user (c-string) +Function output/parameters: None +Function output/returned: one character (chars +Device input/keyboard: user entry of a character +Device output/monitor: prompt string displayed +Dependencies: printf, getChar +*/ +char promptForCharacter( const char *promptString ); + +/* +Name: promptForDouble +Process: prompts user for double, then returns it +Function input/parameters: test to prompt user (c-string) +Function output/parameters: None +Function output/returned: value (double) +Device input/keyboard: user entry of an integer value +Device output/monitor: prompt string displayed +Dependencies: printf, scanf + */ +double promptForDouble( const char *promptString ); + +/* +Name: promptForInteger +Process: prompts user for integer, then returns it +Function input/parameters: text to prompt user (c-string) +Function output/parameters: none +Function output/returned: integer value (int) +Device input/keyboard: user entry of a double value +Device output/monitor: prompt string displayed +Dependencies: printf, scanf +*/ +int promptForInteger( const char *promptString ); + +/* +Name: promptForString +Process: prompts user for string, then returns it +Function input/parameters: text to prompt user (c-string) +Function output/parameters: none +Function output/returned: input string (c-string) +Device input/keyboard: user entry of a string value +Device output/monitor: prompt string displayed +Dependencies: printf, getInputString +*/ +void promptForString( const char *promptString, char returnStr[] ); + +#endif // end CONSOLE_IO_UTILITY_H diff --git a/PA06-1019/File_Input_Utility.c b/PA06-1019/File_Input_Utility.c new file mode 100644 index 0000000..087fced --- /dev/null +++ b/PA06-1019/File_Input_Utility.c @@ -0,0 +1,718 @@ +/* +Formatted file input utility, function implementations + +Copyright (c) 2021 by Michael E. Leverington + +Code is free for use in whole or in part and may be modified for other +non-commercial use as long as the above copyright statement is included. +*/ + +// header files +#include "File_Input_Utility.h" +#include //////////////////////////test + +// local global constants, used only in this file + + // dummy file pointer for accessInputFilePointer + const FILE *DUMMY_INPUT_FILE_PTR = NULL; + + // dummy Boolean for accessEndOfInputFileFlag, accessOpenFlag + const char DUMMY_INPUT_FLAG = false; + + // control code for accessing file pointer, accessInputFilePointer + const int GET_INPUT_FILE_PTR = 3003; + + // control code for accessing flag value, + // accessEndOfInputFileFlag, accessOpenFlag + const int GET_INPUT_FLAG = 2002; + + // control code for setting file pointer, accessInputFilePointer + const int SET_INPUT_FILE_PTR = 4004; + + // control code for setting flag value, accessEndOfInputFileFlag, + // accessOpenFlag + const int SET_INPUT_FLAG = 1001; + + + /* + Name: accessEndOfInputFileFlag + process: allows accessing or modifying end of file flag state; + note: flag is maintained (static) value initialized to false + Function input/parameters: control code (int), flag state (bool) + Function output/parameters: none + Function output/returned: result of flag state (bool) + Device input/file: none + Device output/monitor: none + Dependencies: none + */ + bool accessEndOfInputFileFlag( int ctrlCode, bool setFlag ) + { + // initialize end of file flag to false + static bool endOfFileFlag = false; + + // test for set flag + if( ctrlCode == SET_INPUT_FLAG ) + { + // set flag to given state + endOfFileFlag = setFlag; + } + + // return flag state + return endOfFileFlag; + } + + /* + Name: accessInputFilePointer + process: allows setting or accessing file pointer; + note: pointer is maintained (static) value initialized to NULL + Function input/parameters: control code (int), file pointer (FILE *) + DUMMY_INPUT_FILE_PTR used + if not setting file pointer + Function output/parameters: none + Function output/returned: file pointer (FILE *) + Device input/file: none + Device output/monitor: none + Dependencies: none + */ + FILE *accessInputFilePointer( int ctrlCode, const FILE *filePtr ) + { + // initialize file pointer to null + static FILE *filePointer = NULL; + + // check for set new pointer + if( ctrlCode == SET_INPUT_FILE_PTR ) + { + // set file pointer to parameter + filePointer = (FILE *)filePtr; + } + + // return file pointer + return filePointer; + } + + /* + Name: checkForEndOfInputFile + process: checks to see if end of file flag has been encountered, + returns true if EOF has been encountered, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: result of specified test (bool) + Device input/file: none + Device output/monitor: none + Dependencies: accessEndOfInputFileFlag + */ + bool checkForEndOfInputFile() + { + // return access to end of file flag + // function: accessEndOfInputFileFlag + return accessEndOfInputFileFlag( GET_INPUT_FLAG, DUMMY_INPUT_FLAG ); + } + + /* + Name: checkForInputFileOpen + process: checks to see if file is currently open + returns true if file pointer not null, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: result of specified test (bool) + Device input/file: none + Device output/monitor: none + Dependencies: accessInputFilePointer + */ + bool checkForInputFileOpen() + { + // return access to end of file flag + // function: accessInputFilePointer + return accessInputFilePointer( GET_INPUT_FLAG, + DUMMY_INPUT_FILE_PTR ) != NULL; + } + + /* + Name: clearLeadingWhiteSpace + process: captures non printable characters, + and space if flag set, + returns first non white space value found as integer + Function input/parameters: file pointer (FILE *), clear space flag (bool) + Function output/parameters: none + Function output/returned: first non WS character as integer + Device input/file: value captured from file + Device output/monitor: none + Dependencies: fgetc + */ + int clearLeadingWhiteSpace( FILE *filePtr, bool clearSpace ) + { + // initialize character input value + // function: fgetc + int charInt = fgetc( filePtr ); + + while( + // continue if not at end of file + ( charInt != EOF ) + + // AND + // continue if character is non printable + && ( ( charInt < SPACE ) + + // OR + // continue if clear space flag set and space is found + || ( clearSpace && charInt == SPACE ) ) + ) + { + // capture next character + // function: fgetc + charInt = fgetc( filePtr ); + } + + // return input value as character + return (char)charInt; + } + + /* + Name: closeInputFile + process: closes input file, returns true if successful, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: none + Device input/file: file closed + Device output/monitor: none + Dependencies: accessInputFilePointer, fclose, accessEndOfInputFileFlag + */ + bool closeInputFile() + { + // set local file pointer to working file pointer + // function: accessInputFilePointer + FILE *filePtr = accessInputFilePointer( GET_INPUT_FILE_PTR, + DUMMY_INPUT_FILE_PTR ); + + // check for valid file pointer + if( filePtr != NULL ) + { + // close file + fclose( filePtr ); + + // set pointer to NULL + // function: accessInputFilePointer + accessInputFilePointer( SET_INPUT_FILE_PTR, NULL ); + + // set end of file flag to false + // function: accessEndOfInputFileFlag + accessEndOfInputFileFlag( SET_INPUT_FLAG, false ); + + // return successful operation + return true; + } + + // return failed operation + return false; + } + + /* + Name: openInputFile + process: opens input file, sets file pointer and unsets end of file flag, + returns true if successful, false otherwise + Function input/parameters: file name (c-string) + Function output/parameters: none + Function output/returned: success of operation (bool) + Device input/file: file opened + Device output/monitor: none + Dependencies: fopen, accessInputFilePointer, accessEndOfInputFileFlag + */ + bool openInputFile( const char *fileName ) + { + // initialize variables + FILE *filePtr = NULL; + char readOnlyCharacter[] = "r"; + + // check for file not open + // function: checkForInputFileOpen + if( !checkForInputFileOpen() ) + { + // open file + // function: fopen + filePtr = fopen( fileName, readOnlyCharacter ); + + // check for success of file open + if( filePtr != NULL ) + { + // set pointer in access function + // function: accessInputFilePointer + accessInputFilePointer( SET_INPUT_FILE_PTR, filePtr ); + + // reset end of file flag, if needed + // accessEndOfInputFileFlag + accessEndOfInputFileFlag( SET_INPUT_FLAG, false ); + + // return operation success + return true; + } + } + // end of file not previously opened block + + // return operation failure + return false; + } + + /* + Name: readCharacterFromFile + process: ignores leading unprintable characters, including space, + captures first printable character + Function input/parameters: allow space capture (bool) + Function output/parameters: none + Function output/returned: character found if successful, ZERO_CHAR otherwise + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: readCharacterFromFileConfigured + */ + char readCharacterFromFile() + { + // initialize parameter to not allow space + bool noSpaceCapture = false; + + // capture character, return + // function: getCharFromFileConfigured + return readCharacterFromFileConfigured( noSpaceCapture ); + } + + /* + Name: readCharacterFromFileConfigured + process: ignores leading unprintable characters, + captures first printable character, + including space if allowed + Function input/parameters: allow space capture (bool) + Function output/parameters: none + Function output/returned: character found if successful, ZERO_CHAR otherwise + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, clearLeadingWhiteSpace, + accessEndOfInputFileFlag + */ + char readCharacterFromFileConfigured( bool captureSpace ) + { + // initialize variables + FILE *filePtr; + int intChar = ZERO_CHAR; + + // check for file open and data accessible + // function: checkForInputFileOpen, checkForEndOfInputFile + if( checkForInputFileOpen() && !checkForEndOfInputFile() ) + { + // set file pointer + // function: accessInputFilePointer + filePtr = accessInputFilePointer( GET_INPUT_FILE_PTR, + DUMMY_INPUT_FILE_PTR ); + + // get character + // function: clearLeadingWhiteSpace + intChar = clearLeadingWhiteSpace( filePtr, !captureSpace ); + + // check for end of file found + if( intChar == EOF ) + { + // set end of file flag + // function: accessEndOfInputFileFlag + accessEndOfInputFileFlag( SET_INPUT_FLAG, true ); + + // set return value to zero + intChar = ZERO_CHAR; + } + } + + // return value as character + return intChar; + } + + /* + Name: readDoubleFromFile + process: ignores leading unprintable characters, + captures first contiguous double value + Function input/parameters: none + Function output/parameters: none + Function output/returned: double value found if successful (double) + Device input/file: double value captured from file + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, fscanf, accessEndOfInputFileFlag + */ + double readDoubleFromFile() + { + // initialize variables + FILE *filePtr = NULL; + int fscanfReturn = EOF; + double doubleVal = ZERO_VALUE; + + // check for file open and data accessible + // function: checkForInputFileOpen, checkForEndOfInputFile + if( checkForInputFileOpen() && !checkForEndOfInputFile() ) + { + // set file pointer + // function: accessInputFilePointer + filePtr = accessInputFilePointer( GET_INPUT_FILE_PTR, + DUMMY_INPUT_FILE_PTR ); + + // get double value + // function: fscanf + fscanfReturn = fscanf( filePtr, "%lf", &doubleVal ); + + // check for end of file found + if( fscanfReturn == EOF ) + { + // set end of file flag + // function: accessEndOfInputFileFlag + accessEndOfInputFileFlag( SET_INPUT_FLAG, true ); + + // set return value to zero + doubleVal = ZERO_VALUE; + } + } + + // return acquired value + return doubleVal; + } + + /* + Name: readIntegerFromFile + process: ignores leading unprintable characters, + captures first contiguous integer + Function input/parameters: none + Function output/parameters: none + Function output/returned: integer found if successful, ZERO_VALUE otherwise + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, fscanf, accessEndOfInputFileFlag + */ + int readIntegerFromFile() + { + // initialize variables + FILE *filePtr = NULL; + int fscanfReturn = EOF; + int intVal = ZERO_VALUE; + + // check for file open and data accessible + // function: checkForInputFileOpen, checkForEndOfInputFile + if( checkForInputFileOpen() && !checkForEndOfInputFile() ) + { + // set file pointer + // function: accessInputFilePointer + filePtr = accessInputFilePointer( GET_INPUT_FILE_PTR, + DUMMY_INPUT_FILE_PTR ); + + // get integer value + // function: fscanf + fscanfReturn = fscanf( filePtr, "%d", &intVal ); + + // check for end of file found + if( fscanfReturn == EOF ) + { + // set end of file flag + // function: accessEndOfInputFileFlag + accessEndOfInputFileFlag( SET_INPUT_FLAG, true ); + + // set return value to zero + intVal = ZERO_VALUE; + } + } + + // return acquired value + return intVal; + } + + /* + Name: readLongFromFile + process: ignores leading unprintable characters, + captures first contiguous long int + Function input/parameters: none + Function output/parameters: none + Function output/returned: long integer found if successful, + ZERO_VALUE otherwise + Device input/file: long value captured from file + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, fscanf, accessEndOfInputFileFlag + */ + long readLongFromFile() + { + // initialize variables + FILE *filePtr = NULL; + int fscanfReturn = EOF; + long longVal = ZERO_VALUE; + + // check for file open and data accessible + // function: checkForInputFileOpen, checkForEndOfInputFile + if( checkForInputFileOpen() && !checkForEndOfInputFile() ) + { + // set file pointer + // function: accessInputFilePointer + filePtr = accessInputFilePointer( GET_INPUT_FILE_PTR, + DUMMY_INPUT_FILE_PTR ); + + // get long value + // function: fscanf + fscanfReturn = fscanf( filePtr, "%ld", &longVal ); + + // check for end of file found + if( fscanfReturn == EOF ) + { + // set end of file flag + // function: accessEndOfInputFileFlag + accessEndOfInputFileFlag( SET_INPUT_FLAG, true ); + + // set return value to zero + longVal = ZERO_VALUE; + } + } + + // return acquired value + return longVal; + } + + /* + Name: readRawCharFromFile + process: captures first character in file stream including non-printable + Function input/parameters: none + Function output/parameters: none + Function output/returned: character found if successful, ZERO_CHAR otherwise + Device input/file: character captured from file + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, fgetc, accessEndOfInputFileFlag + */ + char readRawCharFromFile() + { + // initialize variables + FILE *filePtr = NULL; + int intChar = (int)ZERO_CHAR; + + // check for file open and data accessible + // function: checkForInputFileOpen, checkForEndOfInputFile + if( checkForInputFileOpen() && !checkForEndOfInputFile() ) + { + // set file pointer + // function: accessInputFilePointer + filePtr = accessInputFilePointer( GET_INPUT_FILE_PTR, + DUMMY_INPUT_FILE_PTR ); + + // get character + // function: fgetc + intChar = fgetc( filePtr ); + + // check for end of file found + if( intChar == EOF ) + { + // set end of file flag + // function: accessEndOfInputFileFlag + accessEndOfInputFileFlag( SET_INPUT_FLAG, true ); + + // set return value to zero + intChar = (int)ZERO_CHAR; + } + } + + // return acquired value + return (char)intChar; + } + + /* + Name: readStringConfiguredFromFile + Process: captures string with options: + - clear leading non printable (bool) + - clear leading space character (bool) + - adquires characters up to any non-printable (bool) + - adquires characters up to any printable delimiter (char) + - use constant NON_PRINTABLE if no delimiter + - also stops capture when full (MAX_STR_LEN) + Note: This function consumes the last character input, + including the space, delimiter, or non-printable character + Function input/parameters: see process above + Function output/parameters: captured string (char *), EMPTY_STRING otherwise + Function output/returned: success of operation (bool) + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + clearLeadingWhiteSpace, fgetc, accessEndOfInputFileFlag + */ + bool readStringConfiguredFromFile( bool clearLeadingNonPrintable, + bool clearLeadingSpace, + bool stopAtNonPrintable, + char delimiter, + char *capturedString ) + { + // initialize variables + int intChar = EOF, index = 0; + FILE *filePtr = NULL; + + // initialize output string + capturedString[ index ] = NULL_CHAR; + + // check for file open and data accessible + // function: checkForInputFileOpen, checkForEndOfInputFile + if( checkForInputFileOpen() && !checkForEndOfInputFile() ) + { + // get file pointer + // function: accessFilePtr + filePtr = accessInputFilePointer( GET_INPUT_FILE_PTR, + DUMMY_INPUT_FILE_PTR ); + + // check for clearing non printable + if( clearLeadingNonPrintable ) + { + // clear leading white space, with clear space character flag + // function: clearLeadingWhiteSpace + intChar = clearLeadingWhiteSpace( filePtr, clearLeadingSpace ); + } + + // otherwise, assume non printable not cleared + else + { + // get first character + // function: fgetc + intChar = fgetc( filePtr ); + + // check for clearing spaces + if( clearLeadingSpace ) + { + // loop while spaces found and end of file not found + while( intChar != EOF && intChar == (int)SPACE ) + { + // capture new character + // function: fgetc + intChar = fgetc( filePtr ); + } + } + } // end leading character clearing process + + // check for end of file found + if( intChar == EOF ) + { + // set end of file flag + // function: accessEndOfInputFileFlag + accessEndOfInputFileFlag( SET_INPUT_FLAG, true ); + + // return failed operation + return false; + } + + // loop to capture input + while( + // continues if not at end of file and max string length not reached + ( intChar != EOF && index < MAX_STR_LEN - 1 ) + + // AND + // continues if not printable flag set and characters are printable + // OR not printable flag not set + && ( ( stopAtNonPrintable && intChar >= (int)SPACE ) + || ( !stopAtNonPrintable ) ) + + // AND + // continues if specified delimiter is not found + && ( intChar != (char)delimiter ) + ) + { + // place character in array element + capturedString[ index ] = (char)intChar; + + // increment array index + index++; + + // set next element to null character / end of c-string + capturedString[ index ] = NULL_CHAR; + + // get next character as integer + // function: fgetc + intChar = fgetc( filePtr ); + } + // end loop + + // return successful operation + return true; + } + // end of open file and accessible data block + + return false; // temporary stub return + } + + /* + Name: readStringSegmentFromFile + process: ignores leading white space, including space character, + captures series of characters up to first space, + or end of line, or full string + Function input/parameters: none + Function output/parameters: captured string (char *), EMPTY_STRING otherwise + Function output/returned: success of operation (bool) + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: readStringConfigured with appropriate parameters + */ + bool readStringSegmentFromFile( char *capturedString ) + { + // initialize variables + bool clearLeadingNonPrintable = true; + bool clearLeadingSpace = true; + bool stopAtNonPrintable = true; + char delimiter = SPACE; + + // call utility function, return + return readStringConfiguredFromFile( clearLeadingNonPrintable, + clearLeadingSpace, + stopAtNonPrintable, + delimiter, + capturedString ); + } + + /* + Name: readStringToLineEndFromFile + process: ignores leading white space, including space character, + captures series of characters up to end of current line + or full string + Function input/parameters: none + Function output/parameters: captured string (char *), EMPTY_STRING otherwise + Function output/returned: string found if successful + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: readStringConfigured with appropriate parameters + */ + bool readStringToLineEndFromFile( char *capturedString ) + { + // initialize variables + bool clearLeadingNonPrintable = true; + bool clearLeadingSpace = true; + bool stopAtNonPrintable = true; + char delimiter = NON_PRINTABLE; + + // call utility function, return + return readStringConfiguredFromFile( clearLeadingNonPrintable, + clearLeadingSpace, + stopAtNonPrintable, + delimiter, + capturedString ); + } + + /* + Name: readStringToDelimiterFromFile + process: ignores leading white space, including space character, + captures series of characters up to specified character + Function input/parameters: none + Function output/parameters: captured string (char *), EMPTY_STRING otherwise + Function output/returned: string found if successful + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: readStringConfigured with appropriate parameters + */ + bool readStringToDelimiterFromFile( char delimiter, char *capturedString ) + { + // initialize variables + bool clearLeadingNonPrintable = true; + bool clearLeadingSpace = true; + bool stopAtNonPrintable = true; + + // call utility function, return + return readStringConfiguredFromFile( clearLeadingNonPrintable, + clearLeadingSpace, + stopAtNonPrintable, + delimiter, + capturedString ); + } + + + diff --git a/PA06-1019/File_Input_Utility.h b/PA06-1019/File_Input_Utility.h new file mode 100644 index 0000000..b99c78d --- /dev/null +++ b/PA06-1019/File_Input_Utility.h @@ -0,0 +1,296 @@ +/* +Formatted file input utility, function prototypes + +Copyright (c) 2021 by Michael E. Leverington + +Code is free for use in whole or in part and may be modified for other +non-commercial use as long as the above copyright statement is included. +*/ +/* +Rev 0.0: 30 June 2021, Initial creation of file + +UTILITY USAGE INSTRUCTIONS: + +1) This utility contains functions that may be used for file input operations + using the C programming language with text files. + The utility must be linked with the program code with which + it will be used. + +2) Specifications for all the functions + are provided in a standardized format below. + +3) Use this code at your own risk. There is no guarantee of any performance, + implied or otherwise, for any part of this code + + END OF INSTRUCTIONS +*/ + +// PreProcessor test +#ifndef FILE_INPUT_UTILITY_H +#define FILE_INPUT_UTILITY_H + +// header files +#include +#include +#include "StandardConstants.h" + +// constants shared with other files + + // non printable flag, used in getStringConfigured + static const char NON_PRINTABLE = (char)(127); + + // constant used for zero character return + static const char ZERO_CHAR = '0'; + + // constant used for zero int/double value return + static const char ZERO_VALUE = 0; + +// function prototypes + + /* + Name: accessEndOfInputFileFlag + process: allows accessing or modifying end of file flag state; + note: flag is maintained (static) value initialized to false + Function input/parameters: control code (int), flag state (bool) + Function output/parameters: none + Function output/returned: result of flag state (bool) + Device input/file: none + Device output/monitor: none + Dependencies: none + */ + bool accessEndOfInputFileFlag( int ctrlCode, bool setFlag ); + + /* + Name: accessInputFilePointer + process: allows setting or accessing file pointer; + note: pointer is maintained (static) value initialized to NULL + Function input/parameters: control code (int), file pointer (FILE *) + DUMMY_INPUT_FILE_PTR used + if not setting file pointer + Function output/parameters: none + Function output/returned: file pointer (FILE *) + Device input/file: none + Device output/monitor: none + Dependencies: none + */ + FILE *accessInputFilePointer( int ctrlCode, const FILE *filePtr ); + + /* + Name: checkForEndOfInputFile + process: checks to see if end of file flag has been encountered, + returns true if EOF has been encountered, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: result of specified test (bool) + Device input/file: none + Device output/monitor: none + Dependencies: accessEndOfInputFileFlag + */ + bool checkForEndOfInputFile(); + + /* + Name: checkForInputFileOpen + process: checks to see if file is currently open + returns true if file pointer not null, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: result of specified test (bool) + Device input/file: none + Device output/monitor: none + Dependencies: accessInputFilePointer + */ + bool checkForInputFileOpen(); + + /* + Name: clearLeadingWhiteSpace + process: captures non printable characters, + and space if flag set, + returns first non white space value found as integer + Function input/parameters: file pointer (FILE *), clear space flag (bool) + Function output/parameters: none + Function output/returned: first non WS character as integer + Device input/file: value captured from file + Device output/monitor: none + Dependencies: fgetc + */ + int clearLeadingWhiteSpace( FILE *filePtr, bool clearSpace ); + + /* + Name: closeInputFile + process: closes input file, returns true if successful, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: none + Device input/file: file closed + Device output/monitor: none + Dependencies: accessInputFilePointer, fclose, accessEndOfInputFileFlag + */ + bool closeInputFile(); + + /* + Name: openInputFile + process: opens input file, sets file pointer and unsets end of file flag, + returns true if successful, false otherwise + Function input/parameters: file name (c-string) + Function output/parameters: none + Function output/returned: success of operation (bool) + Device input/file: file opened + Device output/monitor: none + Dependencies: fopen, accessInputFilePointer, accessEndOfInputFileFlag + */ + bool openInputFile( const char *fileName ); + + /* + Name: readCharacterFromFile + process: ignores leading unprintable characters, including space, + captures first printable character + Function input/parameters: allow space capture (bool) + Function output/parameters: none + Function output/returned: character found if successful, ZERO_CHAR otherwise + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: readCharacterFromFileConfigured + */ + char readCharacterFromFile(); + + /* + Name: readCharacterFromFileConfigured + process: ignores leading unprintable characters, + captures first printable character, + including space if allowed + Function input/parameters: allow space capture (bool) + Function output/parameters: none + Function output/returned: character found if successful, ZERO_CHAR otherwise + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, clearLeadingWhiteSpace, + accessEndOfInputFileFlag + */ + char readCharacterFromFileConfigured( bool captureSpace ); + + /* + Name: readDoubleFromFile + process: ignores leading unprintable characters, + captures first contiguous double value + Function input/parameters: none + Function output/parameters: none + Function output/returned: double value found if successful (double) + Device input/file: double value captured from file + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, fscanf, accessEndOfInputFileFlag + */ + double readDoubleFromFile(); + + /* + Name: readIntegerFromFile + process: ignores leading unprintable characters, + captures first contiguous integer + Function input/parameters: none + Function output/parameters: none + Function output/returned: integer found if successful, ZERO_VALUE otherwise + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, fscanf, accessEndOfInputFileFlag + */ + int readIntegerFromFile(); + + /* + Name: readLongFromFile + process: ignores leading unprintable characters, + captures first contiguous long int + Function input/parameters: none + Function output/parameters: none + Function output/returned: long integer found if successful, + ZERO_VALUE otherwise + Device input/file: long value captured from file + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, fscanf, accessEndOfInputFileFlag + */ + long readLongFromFile(); + + /* + Name: readRawCharFromFile + process: captures first character in file stream including non-printable + Function input/parameters: none + Function output/parameters: none + Function output/returned: character found if successful, ZERO_CHAR otherwise + Device input/file: character captured from file + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + accessInputFilePointer, fgetc, accessEndOfInputFileFlag + */ + char readRawCharFromFile(); + + /* + Name: readStringConfiguredFromFile + Process: captures string with options: + - clear leading non printable (bool) + - clear leading space character (bool) + - adquires characters up to any non-printable (bool) + - adquires characters up to any printable delimiter (char) + - use constant NON_PRINTABLE if no delimiter + - also stops capture when full (MAX_STR_LEN) + Note: This function consumes the last character input, + including the space, delimiter, or non-printable character + Function input/parameters: see process above + Function output/parameters: captured string (char *), EMPTY_STRING otherwise + Function output/returned: success of operation (bool) + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: checkForInputFileOpen, checkForEndOfInputFile, + clearLeadingWhiteSpace, fgetc, accessEndOfInputFileFlag + */ + bool readStringConfiguredFromFile( bool clearLeadingNonPrintable, + bool clearLeadingSpace, + bool stopAtNonPrintable, + char delimiter, + char *capturedString ); + + /* + Name: readStringSegmentFromFile + process: ignores leading white space, including space character, + captures series of characters up to first space, + or end of line, or full string + Function input/parameters: none + Function output/parameters: captured string (char *), EMPTY_STRING otherwise + Function output/returned: success of operation (bool) + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: readStringConfigured with appropriate parameters + */ + bool readStringSegmentFromFile( char *capturedString ); + + /* + Name: readStringToLineEndFromFile + process: ignores leading white space, including space character, + captures series of characters up to end of current line + or full string + Function input/parameters: none + Function output/parameters: captured string (char *), EMPTY_STRING otherwise + Function output/returned: string found if successful + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: readStringConfigured with appropriate parameters + */ + bool readStringToLineEndFromFile( char *capturedString ); + + /* + Name: readStringToDelimiterFromFile + process: ignores leading white space, including space character, + captures series of characters up to specified character + Function input/parameters: none + Function output/parameters: captured string (char *), EMPTY_STRING otherwise + Function output/returned: string found if successful + Device input/file: character(s) captured from file as needed + Device output/monitor: none + Dependencies: readStringConfigured with appropriate parameters + */ + bool readStringToDelimiterFromFile( char delimiter, char *capturedString ); + +#endif // FILE_INPUT_UTILITY_H + + diff --git a/PA06-1019/File_Output_Utility.c b/PA06-1019/File_Output_Utility.c new file mode 100644 index 0000000..f982995 --- /dev/null +++ b/PA06-1019/File_Output_Utility.c @@ -0,0 +1,511 @@ +/* +Formatted file ouput utility, function implementations + +Copyright (c) 2021 by Michael E. Leverington + +Code is free for use in whole or in part and may be modified for other +non-commercial use as long as the above copyright statement is included. +*/ + +// header files +#include "File_Output_Utility.h" + +// local global constants, used only in this file + + // dummy file pointer for accessInputFilePointer + const FILE *DUMMY_OUTPUT_FILE_PTR = NULL; + + // dummy Boolean for accessEndOfInputFileFlag, accessOpenFlag +// const char DUMMY_OUTPUT_FLAG = false; + + // control code for accessing file pointer, accessInputFilePointer + const int GET_OUTPUT_FILE_PTR = 6006; + + // control code for accessing flag value, + // accessEndOfInputFileFlag, accessOpenFlag + const int GET_OUTPUT_FLAG = 9009; + + // control code for setting file pointer, accessInputFilePointer + const int SET_OUTPUT_FILE_PTR = 8008; + + // control code for setting flag value, accessEndOfInputFileFlag, + // accessOpenFlag +// const int SET_OUTPUT_FLAG = 1001; + + /* + Name: accessOutputFilePointer + process: allows setting or accessing file pointer; + note: pointer is maintained (static) value initialized to NULL + Function input/parameters: control code (int), file pointer (FILE *) + DUMMY_OUTPUT_FILE_PTR used + if not setting file pointer + Function output/parameters: none + Function output/returned: file pointer (FILE *) + Device input/file: none + Device output/monitor: none + Dependencies: none + */ + FILE *accessOutputFilePointer( int ctrlCode, const FILE *filePtr ) + { + static FILE *filePointer = NULL; + + // check for set new pointer + if( ctrlCode == SET_OUTPUT_FILE_PTR ) + { + // set file pointer to parameter + filePointer = (FILE *)filePtr; + } + + // return file pointer + return filePointer; + } + + /* + Name: closeOutputFile + Process: closes output file, returns true if successful, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: output file closed + Dependencies: accessOutputFilePointer, fclose + */ + bool closeOutputFile() + { + // set local file pointer to working file pointer + // function: accessOutputFilePointer + FILE *filePtr = accessOutputFilePointer( GET_OUTPUT_FILE_PTR, + DUMMY_OUTPUT_FILE_PTR ); + + // check for valid file pointer + if( filePtr != NULL ) + { + // add two more endlines to verify that the data is ended + // and has at least one extra newline after the data + // function: fprintf + fprintf( filePtr, "\n\n" ); + + // flush all data to the device + // function: fflush + fflush( filePtr ); + + // close file + // function: fclose + fclose( filePtr ); + + // set pointer to NULL + // function: accessOutputFilePointer + accessOutputFilePointer( SET_OUTPUT_FILE_PTR, NULL ); + + // return successful operation + return true; + } + + // return failed operation + return false; + } + + /* + Name: openOutputFile + Process: opens input file, returns true if successful, false otherwise + Function input/parameters: file name (c-string) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: output file opened + Dependencies: accessOutputFilePointer, fopen + */ + bool openOutputFile( const char *fileName ) + { + // initialize variables + FILE *filePtr = accessOutputFilePointer( GET_OUTPUT_FILE_PTR, + DUMMY_OUTPUT_FILE_PTR ); + char writeCharacter[] = "w"; + + // check for file not open + if( filePtr == NULL ) + { + // open file + // function: fopen + filePtr = fopen( fileName, writeCharacter ); + + // check for success of file open + if( filePtr != NULL ) + { + // set pointer in access function + // function: accessInputFilePointer + accessOutputFilePointer( SET_OUTPUT_FILE_PTR, filePtr ); + + // return operation success + return true; + } + } + // end of file not previously opened block + + // return operation failure + return false; + } + + /* + Name: writeCharacterToFile + Process: writes individual character to file, + returns true if successful, false otherwise + Function input/parameters: character to output (char) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: character written to file + Dependencies: accessOutputFilePointer, fprintf + */ + bool writeCharacterToFile( char outChar ) + { + // initialize variables, set file pointer + // function: accessOutputFilePointer + FILE *filePtr = accessOutputFilePointer( GET_OUTPUT_FILE_PTR, + DUMMY_OUTPUT_FILE_PTR ); + + // check for open file + // function: checkForOutputFileOpen + if( filePtr != NULL ) + { + // write character + // function: fprintf + fprintf( filePtr, "%c", outChar ); + + // return successful operation + return true; + } + + // return failed operation + return false; + } + + /* + Name: writeCharactersToFile + Process: writes multiple characters to file, + returns true if successful, false otherwise + Function input/parameters: number of characters to output (int), + character to output (char) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: multiple characters written to file + Dependencies: writeCharacterToFile + */ + bool writeCharactersToFile( int numChars, char outChar ) + { + // check for number of characters remaining, + if( numChars > 0 ) + { + // write character, check for success + // function: writeChar + if( writeCharacterToFile( outChar ) ) + { + // continue recursion, + // check for downstream success + // function: writeChars + return writeCharactersToFile( numChars - 1, outChar ); + } + + // quit recursion + // return unsuccessful operation - write operation failed + return false; + } + + // return successful operation - all characters have been written + return true; + } + + /* + Name: writeDoubleToFile + Process: writes individual formatted double value to file, + returns true if successful, false otherwise + Function input/parameters: double value to output (double), + number of digits to right of radix point + (precision) (int) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: double written to file + Dependencies: writeDoubleJustifiedToFile + */ + bool writeDoubleToFile( double outVal, int precision ) + { + // initialize variables, set block size to zero and justified to "LEFT" + int blockSize = 0; + char justified[] = "LEFT"; + + // call to justified function + // function: writeDoubleJustifiedToFile + return writeDoubleJustifiedToFile( outVal, precision, + blockSize, justified ); + } + + /* + Name: writeDoubleToFileJustified + Process: writes individual formatted double value to file justified, + returns true if successful, false otherwise + outVal - the double value to be output + precision - number of digits to the right of the radix point + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification + in block (c-string) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: double written to file as specified + Dependencies: sprintf, writeStringJustifiedToFile + */ + bool writeDoubleJustifiedToFile( double outVal, int precision, + int blockSize, const char *justified ) + { + // initialize variables, create temp string for configuration string + char specStr[ MIN_STR_LEN ]; + + // initialize variables, create temporary output string + char outStr[ MIN_STR_LEN ]; + + // set configuration string with precision value + // function: sprintf + sprintf( specStr, "%s0.%dlf", "%", precision ); + + // set double to string + // function: sprintf + sprintf( outStr, specStr, outVal ); + + // write as string, return result + // function: writeStringJustified + return writeStringJustifiedToFile( outStr, blockSize, justified ); + } + + /* + Name: writeEndlineToFile + Process: writes newline ('\n') to file, + returns true if successful, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: newline written to file + Dependencies: accessOutputFilePointer, fprintf + */ + bool writeEndlineToFile() + { + // get file pointer, initialize variable + // function: accessOutputFilePointer + FILE *filePtr = accessOutputFilePointer( GET_OUTPUT_FILE_PTR, + DUMMY_OUTPUT_FILE_PTR ); + + // check for open file + if( filePtr != NULL ) + { + // print endline to file + // function: fprintf + fprintf( filePtr, "%c", NEWLINE_CHAR ); + + // return successful operation + return true; + } + + // file not open, return failed operation + return false; + } + + /* + Name: writeEndlinesToFile + Process: writes multiple carriage return ('\r') + and newline ('\n') pairs to file, + returns true if successful, false otherwise + Function input/parameters: number of endline pairs to write (int) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: multiple newline characters written to file + Dependencies: writeString + */ + bool writeEndlinesToFile( int numEndlines ) + { + // check for number of characters remaining, + if( numEndlines > 0 ) + { + // write endline, check for success + // function: writeEndlineTofile + if( writeEndlineToFile() ) + { + // continue recursion, + // check for downstream success + // function: writeEndlinesToFile + return writeEndlinesToFile( numEndlines - 1 ); + } + + // quit recursion + // return unsuccessful operation - write operation failed + return false; + } + + // return successful operation - all endlines have been written + return true; + } + + /* + Name: writeIntegerToFile + Process: writes individual integer to file, + returns true if successful, false otherwise + Function input/parameters: integer to output (int) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: integer written to file + Dependencies: writeIntegerJustifiedToFile + */ + bool writeIntegerToFile( int outVal ) + { + // initialize variables, set block size to zero and justified to "LEFT" + int blockSize = 0; + char justified[] = "LEFT"; + + // call to justified function + // function: writeDoubleJustifiedToFile + return writeIntegerJustifiedToFile( outVal, blockSize, justified ); + } + + /* + Name: writeIntegerJustifiedToFile + Process: writes individual integer to file, + returns true if successful, false otherwise + Function input/parameters: + outVal - the integer value to be output + precision - number of digits to the right of the radix point + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification + in block (c-string) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: integer written to file as specified + Dependencies: sprintf, writeStringJustifiedToFile + */ + bool writeIntegerJustifiedToFile( int outVal, int blockSize, + const char *justified ) + { + // initialize variables, create temporary output string + char outStr[ MIN_STR_LEN ]; + + // set integer to string + // function: sprintf + sprintf( outStr, "%d", outVal ); + + // write as string, return result + // function: writeStringJustified + return writeStringJustifiedToFile( outStr, blockSize, justified ); + } + + /* + Name: writeStringToFile + Process: writes String value to file, + returns true if successful, false otherwise + Function input/parameters: double value to output (double), + number of digits to right of radix point + (precision) (int) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: String written to file + Dependencies: writeStringJustifiedToFile + */ + bool writeStringToFile( const char *outString ) + { + // initialize variables, set block size to zero and justified to "LEFT" + int blockSize = 0; + char justified[] = "LEFT"; + + // call to justified function + // function: writeStringJustifiedToFile + return writeStringJustifiedToFile( outString, blockSize, justified ); + } + + /* + Name: writeStringJustifiedToFile + Process: write string to file within specified block size + and with specified justification + Function input/parameters: + outVal - the string value to be output + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification + in block (c-string) + Function output/parameters: None + Function output/returned: success of output operation (bool) + Function input/keyboard: None + Device output/file: string written to file as specified + Dependencies: strlen, strcmp, writeCharactersToFile, fprint + */ + bool writeStringJustifiedToFile( const char *outStr, + int blockSize, const char *justify ) + { + // initialize variables, set pre-, post- spaces to zero + int preSpaces = 0, postSpaces = 0, strLength; + + // get file pointer + // function: accessFileOutputFilePointer + FILE *filePtr = accessOutputFilePointer( GET_OUTPUT_FILE_PTR, + DUMMY_OUTPUT_FILE_PTR ); + + if( filePtr != NULL ) + { + // find length of string + // function: strlen + strLength = strlen( outStr ); + + // check justification for "LEFT" + // function: strcmp + if( strcmp( justify, "LEFT" ) == 0 ) + { + // set post spaces for left justification + postSpaces = blockSize - strLength; + } + + // otherwise, check justification for "RIGHT" + // function: strcmp + else if( strcmp( justify, "RIGHT" ) == 0 ) + { + // set pre spaces for right justification + preSpaces = blockSize - strLength; + } + + // Otherwise, assume "CENTER" justification + else + { + // set pre spaces for centered + preSpaces = blockSize / 2 - strLength / 2; + + // set post spaces for centered + postSpaces = blockSize - strLength - preSpaces; + } + + // print pre spaces, check for success + // function: writeCharactersToFile + writeCharactersToFile( preSpaces, SPACE ); + + // print string + // function: fprintf + fprintf( filePtr, "%s", outStr ); + + // print post spaces + // function: printChars + writeCharactersToFile( postSpaces, SPACE ); + + // return successful operation + return true; + } + + // return failed operation + return false; + } + + + + + diff --git a/PA06-1019/File_Output_Utility.h b/PA06-1019/File_Output_Utility.h new file mode 100644 index 0000000..cf06d34 --- /dev/null +++ b/PA06-1019/File_Output_Utility.h @@ -0,0 +1,236 @@ +/* +Formatted file output utility, function prototypes + +Copyright (c) 2021 by Michael E. Leverington + +Code is free for use in whole or in part and may be modified for other +non-commercial use as long as the above copyright statement is included. +*/ +/* +Rev 0.0: 30 June 2021, Initial creation of file + +UTILITY USAGE INSTRUCTIONS: + +1) This utility contains functions that may be used for file input operations + using the C programming language with text files. + The utility must be linked with the program code with which + it will be used. + +2) Specifications for all the functions + are provided in a standardized format below. + +3) Use this code at your own risk. There is no guarantee of any performance, + implied or otherwise, for any part of this code + + END OF INSTRUCTIONS +*/ + +// PreProcessor directives +#ifndef FILE_OUTPUT_UTILITY_H +#define FILE_OUTPUT_UTILITY_H + +// header files +#include +#include +#include +#include "StandardConstants.h" + +// function prototypes + + /* + Name: accessOutputFilePointer + process: allows setting or accessing file pointer; + note: pointer is maintained (static) value initialized to NULL + Function input/parameters: control code (int), file pointer (FILE *) + DUMMY_OUTPUT_FILE_PTR used + if not setting file pointer + Function output/parameters: none + Function output/returned: file pointer (FILE *) + Device input/file: none + Device output/monitor: none + Dependencies: none + */ + FILE *accessOutputFilePointer( int ctrlCode, const FILE *filePtr ); + + /* + Name: closeOutputFile + Process: closes output file, returns true if successful, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: output file closed + Dependencies: accessOutputFilePointer, fclose + */ + bool closeOutputFile(); + + /* + Name: openOutputFile + Process: opens input file, returns true if successful, false otherwise + Function input/parameters: file name (c-string) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: output file opened + Dependencies: accessOutputFilePointer, fopen + */ + bool openOutputFile( const char *fileName ); + + /* + Name: writeCharacterToFile + Process: writes individual character to file, + returns true if successful, false otherwise + Function input/parameters: character to output (char) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: character written to file + Dependencies: accessOutputFilePointer, fprintf + */ + bool writeCharacterToFile( char outChar ); + + /* + Name: writeCharactersToFile + Process: writes multiple characters to file, + returns true if successful, false otherwise + Function input/parameters: number of characters to output (int), + character to output (char) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: multiple characters written to file + Dependencies: writeCharacterToFile + */ + bool writeCharactersToFile( int numChars, char outChar ); + + /* + Name: writeDoubleToFile + Process: writes individual formatted double value to file, + returns true if successful, false otherwise + Function input/parameters: double value to output (double), + number of digits to right of radix point + (precision) (int) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: double written to file + Dependencies: writeDoubleJustifiedToFile + */ + bool writeDoubleToFile( double outVal, int precision ); + + /* + Name: writeDoubleToFileJustified + Process: writes individual formatted double value to file justified, + returns true if successful, false otherwise + outVal - the double value to be output + precision - number of digits to the right of the radix point + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification + in block (c-string) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: double written to file as specified + Dependencies: sprintf, writeStringJustifiedToFile + */ + bool writeDoubleJustifiedToFile( double outVal, int precision, + int blockSize, const char *justified ); + + /* + Name: writeEndlineToFile + Process: writes newline ('\n') to file, + returns true if successful, false otherwise + Function input/parameters: none + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: newline written to file + Dependencies: accessOutputFilePointer, fprintf + */ + bool writeEndlineToFile(); + + /* + Name: writeEndlinesToFile + Process: writes multiple carriage return ('\r') + and newline ('\n') pairs to file, + returns true if successful, false otherwise + Function input/parameters: number of endline pairs to write (int) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: multiple newline characters written to file + Dependencies: writeString + */ + bool writeEndlinesToFile( int numEndlines ); + + /* + Name: writeIntegerToFile + Process: writes individual integer to file, + returns true if successful, false otherwise + Function input/parameters: integer to output (int) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: integer written to file + Dependencies: writeIntegerJustifiedToFile + */ + bool writeIntegerToFile( int outVal ); + + /* + Name: writeIntegerJustifiedToFile + Process: writes individual integer to file, + returns true if successful, false otherwise + Function input/parameters: + outVal - the integer value to be output + precision - number of digits to the right of the radix point + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification + in block (c-string) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: integer written to file as specified + Dependencies: sprintf, writeStringJustifiedToFile + */ + bool writeIntegerJustifiedToFile( int outVal, int blockSize, + const char *justified ); + + /* + Name: writeStringToFile + Process: writes String value to file, + returns true if successful, false otherwise + Function input/parameters: double value to output (double), + number of digits to right of radix point + (precision) (int) + Function output/parameters: none + Function output/returned: operation success (bool) + Device input/file: none + Device output/file: String written to file + Dependencies: writeStringJustifiedToFile + */ + bool writeStringToFile( const char *outString ); + + /* + Name: writeStringJustifiedToFile + Process: write string to file within specified block size + and with specified justification + Function input/parameters: + outVal - the string value to be output + blockSize - the width of the block within which + to print the integer value (int) + justify - "LEFT," "RIGHT," or "CENTER" justification + in block (c-string) + Function output/parameters: None + Function output/returned: success of output operation (bool) + Function input/keyboard: None + Device output/file: string written to file as specified + Dependencies: strlen, strcmp, writeCharactersToFile, fprint + */ + bool writeStringJustifiedToFile( const char *outStr, + int blockSize, const char *justify ); + + +#endif // FILE_OUTPUT_UTILITY_H + diff --git a/PA06-1019/Project_6.c b/PA06-1019/Project_6.c new file mode 100644 index 0000000..2e0f385 --- /dev/null +++ b/PA06-1019/Project_6.c @@ -0,0 +1,143 @@ +// header files +#include "StandardConstants.h" +#include "Console_IO_Utility.h" +#include "File_Input_Utility.h" +#include "File_Output_Utility.h" +#include "Arizona_Tax_Utility.h" + +// constants + // none + +// function prototypes + +/* +Name: createOutputString +Process: creates string to be displayed and output to file; + only one string can be assembled in the function +Function input/parameters: the output string pointer, tax year and tax +Function output/parameters: the generated output string (char *) +Function output/returned: none +Function input/keyboard: none +Device output/file: none +Dependencies: sprintf +*/ +void createOutputString(char *outputString, int taxYear, double totalTax); + +/* +Name: outputResultsToFile +Process: opens file for output, writes string to file with endline, + closes file +Function input/parameters: file name (const char *), + output string (const char *) +Function output/parameters: none +Function output/returned: none +Function input/keyboard: none +Device output/file: none +Dependencies: File Output Utility tools +*/ +void outputResultsToFile(const char *outputFileName, const char *outputString); + +// main program +int main() + { + // show title + // Functions: printf + printf("\nDUMMY TAX CALCULATOR V0.4\n=========================\n\n"); + + // initialize variables + char taxInformationFile[STD_STR_LEN]; + char outputString[STD_STR_LEN], outputFileName[STD_STR_LEN]; + double taxArizona, currentIncome; + int yearCount, currentYear; + yearCount = 0; + + // get user input + // Functions: promptForString + promptForString("Enter file name containing tax information: ", + taxInformationFile); + // conduct calculations + // Functions: calculateArizonaTax, outputResultsToFile + + // open input file + openInputFile(taxInformationFile); + + // use a while loop to iterate over the numbers of years, prime with + // first year. + currentYear = readIntegerFromFile(); + currentIncome = readDoubleFromFile(); + yearCount = yearCount + 1; + while (!checkForEndOfInputFile()) { + sprintf(outputFileName, "Tax_Report_%d.txt", currentYear); + taxArizona = calculateArizonaTax(currentIncome); + createOutputString(outputString, currentYear, taxArizona); + outputResultsToFile(outputFileName, outputString); + yearCount = yearCount + 1; + currentYear = readIntegerFromFile(); + currentIncome = readDoubleFromFile(); + } + + // display results + // Functions: sprintf, printf + printf("\nArizona tax for %d years has been calculated.\n", yearCount - 1); + printf("\nThe results can be viewed in the report files.\n"); + + // end program, return success + printf("\nEnd Program\n"); + return 0; + } + + +// supporting functions + +/* +Name: createOutputString +Process: creates string to be displayed and output to file; + only one string can be assembled in the function +Function input/parameters: the output string pointer, tax year and tax +Function output/parameters: the generated output string (char *) +Function output/returned: none +Function input/keyboard: none +Device output/file: none +Dependencies: sprintf +*/ + +void createOutputString(char *outputString, int taxYear, double totalTax) +{ + // initialize variables + // none + // get user input + // input is passed into function by parameters. + // conduct calculations + // none + // display results + sprintf(outputString, "For the tax year %d total" + " AZ tax to be paid is $%.2f.", taxYear, totalTax); +} + +/* +Name: outputResultsToFile +Process: opens file for output, writes string to file with endline, + closes file +Function input/parameters: file name (const char *), + output string (const char *) +Function output/parameters: none +Function output/returned: none +Function input/keyboard: none +Device output/file: none +Dependencies: File Output Utility tools +*/ + +void outputResultsToFile(const char *outputFileName, const char *outputString) +{ + // initialize variables + // none + // get user input + // input is passed into function by parameters. + // conduct calculations + // none + // display results + // outputs a file + openOutputFile(outputFileName); + writeStringToFile(outputString); + closeOutputFile(); +} diff --git a/PA06-1019/StandardConstants.h b/PA06-1019/StandardConstants.h new file mode 100644 index 0000000..f2babc9 --- /dev/null +++ b/PA06-1019/StandardConstants.h @@ -0,0 +1,51 @@ +// Preprocessor directives +#ifndef STANDARD_CONSTANTS_H +#define STANDARD_CONSTANTS_H + +// Include Boolean +#include + +// global constants + +// constant for end of c-string null character +#define CARRIAGE_RETURN_CHAR '\r' + +//constant for a COLON +#define COLON ':' + +//constant for a COMMA +#define COMMA ',' + +//Constant to print a dash +#define DASH '-' + +// constant for end of c-string null character +#define NEWLINE_CHAR '\n' + +// constant for small string length +#define MIN_STR_LEN 32 + +// constant for maximum string length +#define MAX_STR_LEN 128 + +// constant for end of c-string null character +#define NULL_CHAR '\0' + +//Constant for printing a pipe +#define PIPE '|' + +//Constant for a period +#define PERIOD '.' + +//Constant for PRECISION +#define PRECISION 2 + +// constant for space character +#define SPACE ' ' + +// constant for standard string length +#define STD_STR_LEN 64 + +#endif // STANDARD_CONSTANTS + + diff --git a/PA06-1019/Tax_Information.txt b/PA06-1019/Tax_Information.txt new file mode 100644 index 0000000..a65d985 --- /dev/null +++ b/PA06-1019/Tax_Information.txt @@ -0,0 +1,17 @@ +2001 +14000.50 +2002 +16000.30 +2003 +14500.50 +2005 +17000.90 +2006 +27000.80 +2010 +580000.20 +2021 +1000000 +12022 +100.0 + diff --git a/PA06-1019/test_run_data.txt b/PA06-1019/test_run_data.txt new file mode 100644 index 0000000..e875993 --- /dev/null +++ b/PA06-1019/test_run_data.txt @@ -0,0 +1,7 @@ +2001 +14000.50 +2002 +15000.30 +2003 +650000.20 +