diff --git a/PA08-1101/Balanced_SampleRun.txt b/PA08-1101/Balanced_SampleRun.txt new file mode 100644 index 0000000..1dd691e --- /dev/null +++ b/PA08-1101/Balanced_SampleRun.txt @@ -0,0 +1,288 @@ +Red Black Tree Test Program +=========================== + +Inserting M and resolving + - Root color set to black + +Inserting G and resolving + + B + R B + B B +-------- + + M + G - + - - +======== + +Inserting R and resolving + + B + R R + B B B B +-------- + + M + G R + - - - - +======== + +Inserting B and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + - Root color set to black + + B + B B + R B B B + B B +---------------- + + M + G R + B - - - + - - +================ + + B + B B + R B B B + B B +---------------- + + M + G R + B - - - + - - +================ + +Inserting J and resolving + + B + B B + R R B B + B B B B +---------------- + + M + G R + B J - - + - - - - +================ + +Inserting P and resolving + + B + B B + R R R B + B B B B B B +---------------- + + M + G R + B J P - + - - - - - - +================ + +Inserting U and resolving + + B + B B + R R R R + B B B B B B B B +---------------- + + M + G R + B J P U + - - - - - - - - +================ + +Inserting A and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + + B + R B + B B R R + R B B B B B B B + B B +-------------------------------- + + M + G R + B J P U + A - - - - - - - + - - +================================ + + B + R B + B B R R + R B B B B B B B + B B +-------------------------------- + + M + G R + B J P U + A - - - - - - - + - - +================================ + +Inserting C and resolving + + B + R B + B B R R + R R B B B B B B + B B B B +-------------------------------- + + M + G R + B J P U + A C - - - - - - + - - - - +================================ + +Inserting H and resolving + + B + R B + B B R R + R R R B B B B B + B B B B B B +-------------------------------- + + M + G R + B J P U + A C H - - - - - + - - - - - - +================================ + +Inserting L and resolving + + B + R B + B B R R + R R R R B B B B + B B B B B B B B +-------------------------------- + + M + G R + B J P U + A C H L - - - - + - - - - - - - - +================================ + +Inserting N and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + + B + R R + B B B B + R R R R R B B B + B B B B B B B B B B +-------------------------------- + + M + G R + B J P U + A C H L N - - - + - - - - - - - - - - +================================ + + B + R R + B B B B + R R R R R B B B + B B B B B B B B B B +-------------------------------- + + M + G R + B J P U + A C H L N - - - + - - - - - - - - - - +================================ + +Inserting Q and resolving + + B + R R + B B B B + R R R R R R B B + B B B B B B B B B B B B +-------------------------------- + + M + G R + B J P U + A C H L N Q - - + - - - - - - - - - - - - +================================ + +Inserting S and resolving + + B + R R + B B B B + R R R R R R R B + B B B B B B B B B B B B B B +-------------------------------- + + M + G R + B J P U + A C H L N Q S - + - - - - - - - - - - - - - - +================================ + +Inserting X and resolving + + B + R R + B B B B + R R R R R R R R + B B B B B B B B B B B B B B B B +-------------------------------- + + M + G R + B J P U + A C H L N Q S X + - - - - - - - - - - - - - - - - +================================ + +Inorder : A/R; B/B; C/R; G/R; H/R; J/B; L/R; M/B; N/R; P/B; Q/R; R/R; S/R; U/B; X/R + +Postorder: A/R; C/R; B/B; H/R; L/R; J/B; G/R; N/R; Q/R; P/B; S/R; X/R; U/B; R/R; M/B + +Preorder : M/B; G/R; B/B; A/R; C/R; J/B; H/R; L/R; R/R; P/B; N/R; Q/R; U/B; S/R; X/R + +Copying Tree + M + G R + B J P U + A C H L N Q S X + - - - - - - - - - - - - - - - - + +End Program + diff --git a/PA08-1101/Console_IO_Utility.c b/PA08-1101/Console_IO_Utility.c new file mode 100644 index 0000000..38b9f46 --- /dev/null +++ b/PA08-1101/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/PA08-1101/Console_IO_Utility.h b/PA08-1101/Console_IO_Utility.h new file mode 100644 index 0000000..cb76f1c --- /dev/null +++ b/PA08-1101/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 + Function output/parameters: 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 input/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) + Function output/parameters: 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: + outStr - 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: input string captured (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[] ); + +#endif // end CONSOLE_IO_UTILITY_H diff --git a/PA08-1101/File_Input_Utility.c b/PA08-1101/File_Input_Utility.c new file mode 100644 index 0000000..a7bbd68 --- /dev/null +++ b/PA08-1101/File_Input_Utility.c @@ -0,0 +1,717 @@ +/* +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 < (int)SPACE || charInt > (int)HIGHEST_PRINTABLE_CHAR ) + + // 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/PA08-1101/File_Input_Utility.h b/PA08-1101/File_Input_Utility.h new file mode 100644 index 0000000..70d3552 --- /dev/null +++ b/PA08-1101/File_Input_Utility.h @@ -0,0 +1,295 @@ +/* +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/PA08-1101/File_Output_Utility.c b/PA08-1101/File_Output_Utility.c new file mode 100644 index 0000000..f982995 --- /dev/null +++ b/PA08-1101/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/PA08-1101/File_Output_Utility.h b/PA08-1101/File_Output_Utility.h new file mode 100644 index 0000000..cf06d34 --- /dev/null +++ b/PA08-1101/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/PA08-1101/LeftLeft_SampleRun.txt b/PA08-1101/LeftLeft_SampleRun.txt new file mode 100644 index 0000000..bae3bb2 --- /dev/null +++ b/PA08-1101/LeftLeft_SampleRun.txt @@ -0,0 +1,308 @@ +Red Black Tree Test Program +=========================== + +Inserting Z and resolving + - Root color set to black + +Inserting Y and resolving + + B + R B + B B +-------- + + Z + Y - + - - +======== + +Inserting X and resolving + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + R R + B B B B +-------- + + Y + X Z + - - - - +======== + +Inserting W and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + - Root color set to black + + B + B B + R B B B + B B +---------------- + + Y + X Z + W - - - + - - +================ + + B + B B + R B B B + B B +---------------- + + Y + X Z + W - - - + - - +================ + +Inserting V and resolving + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + B B + R R B B + B B B B +---------------- + + Y + W Z + V X - - + - - - - +================ + +Inserting U and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + + B + R B + B B B B + R B B B + B B +-------------------------------- + + Y + W Z + V X - - + U - - - + - - +================================ + + B + R B + B B B B + R B B B + B B +-------------------------------- + + Y + W Z + V X - - + U - - - + - - +================================ + +Inserting T and resolving + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + R B + B B B B + R R B B + B B B B +-------------------------------- + + Y + W Z + U X - - + T V - - + - - - - +================================ + +Inserting S and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + R R + B B B B + R B B B B B B B + B B +-------------------------------- + + W + U Y + T V X Z + S - - - - - - - + - - +================================ + + B + R R + B B B B + R B B B B B B B + B B +-------------------------------- + + W + U Y + T V X Z + S - - - - - - - + - - +================================ + +Inserting R and resolving + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + R R + B B B B + R R B B B B B B + B B B B +-------------------------------- + + W + U Y + S V X Z + R T - - - - - - + - - - - +================================ + +Inserting Q and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + - Root color set to black + + B + B B + R B B B + B B B B B B B B + R B B B + B B +---------------------------------------------------------------- + + W + U Y + S V X Z + R T - - - - - - + Q - - - + - - +================================================================ + + B + B B + R B B B + B B B B B B B B + R B B B + B B +---------------------------------------------------------------- + + W + U Y + S V X Z + R T - - - - - - + Q - - - + - - +================================================================ + + B + B B + R B B B + B B B B B B B B + R B B B + B B +---------------------------------------------------------------- + + W + U Y + S V X Z + R T - - - - - - + Q - - - + - - +================================================================ + +Inserting P and resolving + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + B B + R B B B + B B B B B B B B + R R B B + B B B B +---------------------------------------------------------------- + + W + U Y + S V X Z + Q T - - - - - - + P R - - + - - - - +================================================================ + +Inorder : P/R; Q/B; R/R; S/R; T/B; U/B; V/B; W/B; X/B; Y/B; Z/B + +Postorder: P/R; R/R; Q/B; T/B; S/R; V/B; U/B; X/B; Z/B; Y/B; W/B + +Preorder : W/B; U/B; S/R; Q/B; P/R; R/R; T/B; V/B; Y/B; X/B; Z/B + +Copying Tree + W + U Y + S V X Z + Q T - - - - - - + P R - - + - - - - + +End Program + diff --git a/PA08-1101/Makefile b/PA08-1101/Makefile new file mode 100644 index 0000000..c5da7c5 --- /dev/null +++ b/PA08-1101/Makefile @@ -0,0 +1,37 @@ +CC = gcc -Wall +SOURCES = PA08_Main.c RedBlackTreeUtility.c Console_IO_Utility.c File_Input_Utility.c File_Output_Utility.c +OBJECTS = PA08_Main.o RedBlackTreeUtility.o Console_IO_Utility.o File_Input_Utility.o File_Output_Utility.o + +# Uses the template structure defined in the TypicalUtils folder + +all: PA08_Main + +PA08_Main: $(OBJECTS) + $(CC) $(OBJECTS) -o PA08_Main + +PA08_Main.o: PA08_Main.c + $(CC) -c PA08_Main.c -o PA08_Main.o + +RedBlackTreeUtility.o: RedBlackTreeUtility.c + $(CC) -c RedBlackTreeUtility.c -o RedBlackTreeUtility.o + +Console_IO_Utility.o: Console_IO_Utility.c + $(CC) -c Console_IO_Utility.c -o Console_IO_Utility.o + +File_Input_Utility.o: File_Input_Utility.c + $(CC) -c File_Input_Utility.c -o File_Input_Utility.o + +File_Output_Utility.o: File_Output_Utility.c + $(CC) -c File_Output_Utility.c -o File_Output_Utility.o + +clean: + rm -f $(OBJECTS) PA08_Main PA08_Main.out + +clean_objects: + rm -f $(OBJECTS) + +run: + ./PA08_Main + +run_win: + PA08_Main diff --git a/PA08-1101/PA08_Main.c b/PA08-1101/PA08_Main.c new file mode 100644 index 0000000..9992201 --- /dev/null +++ b/PA08-1101/PA08_Main.c @@ -0,0 +1,95 @@ +// header files +#include "RedBlackTreeUtility.h" + +// constant definitions + // none + +// prototypes + // none + +// main function +int main( int argc, char *argv[] ) + { + RedBlackNodeType *treeRoot, *cpdTreeRoot; + //char stateString[ STD_STR_LEN ]; + + // set title + printf( "\nRed Black Tree Test Program\n" ); + printf( "===========================\n" ); + + // initialize tree + treeRoot = initializeRBT(); + cpdTreeRoot = initializeRBT(); + + // balanced cases + + treeRoot = insert( treeRoot, 'M' ); + treeRoot = insert( treeRoot, 'G' ); + treeRoot = insert( treeRoot, 'R' ); + treeRoot = insert( treeRoot, 'B' ); + treeRoot = insert( treeRoot, 'J' ); + treeRoot = insert( treeRoot, 'P' ); + treeRoot = insert( treeRoot, 'U' ); + treeRoot = insert( treeRoot, 'A' ); + treeRoot = insert( treeRoot, 'C' ); + treeRoot = insert( treeRoot, 'H' ); + treeRoot = insert( treeRoot, 'L' ); + treeRoot = insert( treeRoot, 'N' ); + treeRoot = insert( treeRoot, 'Q' ); + treeRoot = insert( treeRoot, 'S' ); + treeRoot = insert( treeRoot, 'X' ); + + // Right right cases +/* + treeRoot = insert( treeRoot, 'G' ); + treeRoot = insert( treeRoot, 'H' ); + treeRoot = insert( treeRoot, 'I' ); + treeRoot = insert( treeRoot, 'J' ); + treeRoot = insert( treeRoot, 'K' ); + treeRoot = insert( treeRoot, 'F' ); + treeRoot = insert( treeRoot, 'E' ); + treeRoot = insert( treeRoot, 'D' ); + treeRoot = insert( treeRoot, 'C' ); + treeRoot = insert( treeRoot, 'B' ); + treeRoot = insert( treeRoot, 'A' ); +*/ + // Left left cases +/* + treeRoot = insert( treeRoot, 'Z' ); + treeRoot = insert( treeRoot, 'Y' ); + treeRoot = insert( treeRoot, 'X' ); + treeRoot = insert( treeRoot, 'W' ); + treeRoot = insert( treeRoot, 'V' ); + treeRoot = insert( treeRoot, 'U' ); + treeRoot = insert( treeRoot, 'T' ); + treeRoot = insert( treeRoot, 'S' ); + treeRoot = insert( treeRoot, 'R' ); + treeRoot = insert( treeRoot, 'Q' ); + treeRoot = insert( treeRoot, 'P' ); +*/ + displayTree( treeRoot, INORDER_TRAVERSE ); + displayTree( treeRoot, POSTORDER_TRAVERSE ); + displayTree( treeRoot, PREORDER_TRAVERSE ); + + // copy tree + printf( "\nCopying Tree\n" ); + cpdTreeRoot = copyTree( treeRoot ); + + displayTreeStructure( cpdTreeRoot, NODE_DATA ); + + // end program + + // clear RBT + // function: clearTree + treeRoot = clearTree( treeRoot ); + cpdTreeRoot = clearTree( cpdTreeRoot ); + + // show program end + // function: printf + printf( "\nEnd Program\n" ); + + // return success + return 0; + } + + diff --git a/PA08-1101/RedBlackTreeUtility.c b/PA08-1101/RedBlackTreeUtility.c new file mode 100644 index 0000000..f4fa8f0 --- /dev/null +++ b/PA08-1101/RedBlackTreeUtility.c @@ -0,0 +1,278 @@ +// Header file +#include "RedBlackTreeUtility.h" + +// constants +const char SEMICOLON_BREAK[] = "; "; +const char THICK_DIVIDER = '='; +const char THIN_DIVIDER = '-'; + +// functions + +// TODO: Set functions here + +//////////////////////////////////////////////////////////////////////////////// +// No student coding below this point +//////////////////////////////////////////////////////////////////////////////// + +/* +Name: displayAtTreeLevel +Process: displays one horizontal "level" of a tree using text graphics + with appropriate spacing and appropriate number of nodes +Function input/parameters: recursive working node (RedBlackNodeType *), + node height, display level, working level (int), + row start flag (bool), + control code for either data or color +Function output/parameters: none +Function output/returned: updated row start flag (bool *) +Device input/file: none +Device output/monitor: none +Dependencies: displayValue, displayEmptyNodeSpaces +*/ +void displayAtTreeLevel( RedBlackNodeType *workingNode, int nodeHeight, + int displayLevel, int workingLevel, + bool *rowStartFlag, ControlCodes ctrlCode ) + { + char charOut = workingNode->data; + + if( ctrlCode == NODE_COLOR ) + { + charOut = (char)workingNode->color; + } + + if( workingLevel == displayLevel ) + { + displayValue( charOut, nodeHeight, workingLevel, rowStartFlag ); + } + + else + { + if( workingNode->leftChildPtr != NULL ) + { + displayAtTreeLevel( workingNode->leftChildPtr, nodeHeight, + displayLevel, workingLevel + 1, rowStartFlag, ctrlCode ); + } + + else + { + displayEmptyNodeSpaces( nodeHeight, displayLevel, + workingLevel + 1, rowStartFlag, ctrlCode ); + } + + if( workingNode->rightChildPtr != NULL ) + { + displayAtTreeLevel( workingNode->rightChildPtr, nodeHeight, + displayLevel, workingLevel + 1, rowStartFlag, ctrlCode ); + } + + else + { + displayEmptyNodeSpaces( nodeHeight, displayLevel, + workingLevel + 1, rowStartFlag, ctrlCode ); + } + } + } + +/* +Name: displayChars +Process: recursively displays a specified number of specified characters +Function input/parameters: number of characters (int), + character to be displayed (char) +Function output/parameters: none +Function output/returned: none +Device input/file: none +Device output/monitor: characters displayed as specified +Dependencies: printf +*/ +void displayChars( int numChars, char outChar ) + { + if( numChars > 0 ) + { + printf( "%c", outChar ); + + displayChars( numChars - 1, outChar ); + } + } + +/* +Name: displayDivider +Process: displays divider of correct length for tree + using either THICK_DIVIDER or THIN_DIVIDER + depending on the control code, + adds one endline to thick divider, two to thin for spacing +Function input/parameters: number of characters (int), + character to be displayed (char) +Function output/parameters: none +Function output/returned: none +Device input/file: none +Device output/monitor: characters displayed as specified +Dependencies: printf +*/ +void displayDivider( RedBlackNodeType *rootPtr, char dividerChar ) + { + int treeHeight = findTreeHeight( rootPtr ); + int numChars = toPower( 2, treeHeight + 2 ); + + displayChars( numChars, dividerChar ); + + if( dividerChar == THIN_DIVIDER ) + { + printf( "\n" ); + } + + printf( "\n" ); + } + +/* +Name: displayEmptyNodeSpaces +Process: displays the appropriate number of dashes for a given level + for null nodes, can display either dashes or 'B's +Function input/parameters: node height, display level, working level (int) + pointer to row start flag (bool *), + control code for either data or color +Function output/parameters: none +Function output/returned: updated row start flag (bool *) +Device input/file: none +Device output/monitor: characters displayed as specified +Dependencies: toPower, displayValue +*/ +void displayEmptyNodeSpaces( int nodeHeight, + int displayLevel, int workingLevel, + bool *rowStartFlag, ControlCodes ctrlCode ) + { + int nodesToDisplay = toPower( 2, displayLevel - workingLevel ); + char charOut = SPACE; + + if( displayLevel == workingLevel ) + { + charOut = DASH; + + if( ctrlCode == NODE_COLOR ) + { + charOut = 'B'; + } + } + + while( nodesToDisplay > 0 ) + { + displayValue( charOut, nodeHeight, displayLevel, rowStartFlag ); + + nodesToDisplay--; + } + } + +/* +Name: displayTreeStructure +Process: repeatedly calls other function to display + the structure of an RB tree, can display either dashes or 'B's, + displays error message if empty tree +Function input/parameters: tree root pointer (RedBlackNodeType *), + control code for either data or color +Function output/parameters: none +Function output/returned: none +Device input/file: none +Device output/monitor: characters displayed as specified +Dependencies: findTreeHeight, displayAtTreeLevel, printf +*/ +void displayTreeStructure( RedBlackNodeType *rbTreeRoot, ControlCodes ctrlCode ) + { + int displayLevel, nodeHeight = findTreeHeight( rbTreeRoot ) + 2; + int workingLevel = 1; + bool rowStartFlag; + + if( rbTreeRoot != NULL ) + { + for( displayLevel = 1; displayLevel <= nodeHeight; displayLevel++ ) + { + rowStartFlag = true; + + displayAtTreeLevel( rbTreeRoot, nodeHeight, + displayLevel, workingLevel, &rowStartFlag, ctrlCode ); + + printf( "\n" ); + } + } + + else + { + printf( "\nEmpty Tree - No Display" ); + } + } + +/* +Name: displayValue +Process: displays a tree character value or color letter (R/B) + after a calculated set of leading spaces +Function input/parameters: character data (char), + node height, working level (int), + pointer to row start flag (bool *) +Function output/parameters: updated row start flag (bool *) +Function output/returned: none +Device input/file: none +Device output/monitor: character displayed as specified +Dependencies: toPower, displayChars, printf +*/ +void displayValue( char data, int nodeHeight, + int workingLevel, bool *rowStartFlag ) + { + int leadingSpaces; + + if( *rowStartFlag ) + { + leadingSpaces = toPower( 2, nodeHeight - workingLevel ); + + *rowStartFlag = false; + } + + else + { + leadingSpaces = toPower( 2, nodeHeight - workingLevel + 1 ) - 1; + } + + displayChars( leadingSpaces, SPACE ); + + printf( "%c", data ); + } + +/* +Name: getMax +Process: finds the maximum between two values, returns +Function input/parameters: two values (int) +Function output/parameters: none +Function output/returned: maximum of two values (int) +Device input/file: none +Device output/monitor: none +Dependencies: none +*/ +int getMax( int one, int other ) + { + int max = one; + + if( other > max ) + { + max = other; + } + + return max; + } + +/* +Name: toPower +Process: recursively calculates a base to exponent value + for positive integer exponents +Function input/parameters: base, exponent (int) +Function output/parameters: none +Function output/returned: calculated value (int) +Device input/file: none +Device output/monitor: none +Dependencies: none +*/ +int toPower( int base, int exponent ) + { + if( exponent > 0 ) + { + return toPower( base, exponent - 1 ) * base; + } + + return 1; + } + diff --git a/PA08-1101/RedBlackTreeUtility.h b/PA08-1101/RedBlackTreeUtility.h new file mode 100644 index 0000000..665bebb --- /dev/null +++ b/PA08-1101/RedBlackTreeUtility.h @@ -0,0 +1,397 @@ +#ifndef RED_BLACK_TREE_UTILITY_H +#define RED_BLACK_TREE_UTILITY_H + +// Header files +#include "StandardConstants.h" +#include // NULL +#include // printf + +// constants + +// node colors +typedef enum { BLACK = 66, RED = 82 } Colors; + +// allows user to choose color or data in tree display +typedef enum { PREORDER_TRAVERSE = 101, INORDER_TRAVERSE = 102, + POSTORDER_TRAVERSE = 103, NODE_COLOR = 191, + NODE_DATA = 192 } ControlCodes; + +// data structures + +typedef struct RedBlackNodeStruct + { + Colors color; + + char data; + + struct RedBlackNodeStruct *parentPtr, *leftChildPtr, *rightChildPtr; + + } RedBlackNodeType; + +// prototypes + +/* +Name: clearTree +Process: recursively returns dynamically allocated data to the OS + using a post order traversal strategy +Function input/parameters: working pointer for recursion (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: empty tree (NULL) +Device input/---: none +Device output/---: none +Dependencies: free +*/ +RedBlackNodeType *clearTree( RedBlackNodeType *localPtr ); + +/* +Name: copyTree +Process: copies a Red Black tree from another Red Black tree + using a pre order traversal strategy, + appropriately links child parent pointers to current node +Function input/parameters: pointer to source node (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: pointer to destination node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: createNodeFromNode, copyTree (recursively) +*/ +RedBlackNodeType *copyTree( RedBlackNodeType *srcPtr ); + +/* +Name: createNodeFromData +Process: creates a Red Black tree node from the node data given, + all links are set to NULL +Function input/parameters: data (char), color (int) +Function output/parameters: none +Function output/returned: pointer to created node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: malloc +*/ +RedBlackNodeType *createNodeFromData( char data, int nodeColor ); + +/* +Name: createNodeFromNode +Process: allocates memory for node, + copies an individual tree node from another node, + all links are set to NULL +Function input/parameters: pointer to source node (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: pointer to destination node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: one line of code - createNodeFromData +*/ +RedBlackNodeType *createNodeFromNode( RedBlackNodeType *srcPtr ); + +/* +Name: displayInOrder +Process: traverses across tree, prints semicolon-delimited list, + displays "data / color" using in order strategy +Function input/parameters: pointer to current working node (RedBlackNodeType *), + pointer to row start flag + for first line of output (bool *) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: displayed as specified +Dependencies: printf, displayInOrder (recursively) +*/ +void displayInOrder( RedBlackNodeType *wkgPtr, bool *rowStartFlag ); + +/* +Name: displayPostOrder +Process: traverses across tree, prints semicolon-delimited list, + displays "data / color" using post order strategy +Function input/parameters: pointer to current working node (RedBlackNodeType *), + pointer to row start flag + for first line of output (bool *) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: displayed as specified +Dependencies: printf, displayPostOrder (recursively) +*/ +void displayPostOrder( RedBlackNodeType *wkgPtr, bool *rowStartFlag ); + +/* +Name: displayPreOrder +Process: traverses across tree, prints semicolon-delimited list, + displays "data / color" using pre order strategy +Function input/parameters: pointer to current working node (RedBlackNodeType *), + pointer to row start flag + for first line of output (bool *) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: displayed as specified +Dependencies: printf, displayPreOrder (recursively) +*/ +void displayPreOrder( RedBlackNodeType *wkgPtr, bool *rowStartFlag ); + +/* +Name: displayTree +Process: controller function for calling appropriate tree traversal +Function input/parameters: pointer to current tree root (RedBlackNodeType *), + control codes INORDER_TRAVERSE, POSTORDER_TRAVERSE, + PREORDER_TRAVERSE +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: displayed as specified +Dependencies: displayInOrder, displayPostOrder, displayPreOrder, printf +*/ +void displayTree( RedBlackNodeType *rootPtr, ControlCodes traverseCode ); + +/* +Name: findTreeHeight +Process: recursively finds height of tree +Function input/parameters: working pointer for recursion (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: height of tree (int) +Device input/---: none +Device output/---: none +Dependencies: getMax +*/ +int findTreeHeight( RedBlackNodeType *localPtr ); + +/* +Name: initializeRBT +Process: returns NULL to tree root pointer to prepare tree for use +Function input/parameters: none +Function output/parameters: none +Function output/returned: NULL +Device input/---: none +Device output/---: none +Dependencies: none +*/ +RedBlackNodeType *initializeRBT(); + +/* +Name: insert +Process: sets first node if tree is empty, otherwise calls helper + to set nodes, then calls RBT resolver to rebalance tree + if node is successfully inserted by helper, + prints inserting/resolving statement and root color set to black +Function input/parameters: tree root pointer (RedBlackNodeType *), + data to be inserted (char) +Function output/parameters: none +Function output/returned: pointer to updated tree root (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: printf, createNodeFromData, insertHelper, resolveRBT +*/ +RedBlackNodeType *insert( RedBlackNodeType *treeRoot, char inData ); + +/* +Name: insertHelper +Process: recursively finds place to add node, + places node using "look down" strategy, + returns newly inserted node pointer, + if duplicated nodes/keys attempted, returns NULL +Function input/parameters: working pointer for recursion (RedBlackNodeType *), + data to be inserted (char) +Function output/parameters: none +Function output/returned: pointer to inserted node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: createNodeFromData, insertHelper (recursively) +*/ +RedBlackNodeType *insertHelper( RedBlackNodeType *wkgPtr, char inData ); + +/* +Name: isEmpty +Process: returns true if tree is empty, false otherwise +Function input/parameters: tree root pointer (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: result of test (bool) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +bool isEmpty( RedBlackNodeType *localPtr ); + +/* +Name: resolveRBT +Process: recursively checks tree for need to rebalance, + conducts rebalance as needed +Function input/parameters: address of tree root pointer (RedBlackNodeType **), + working pointer for recursion + which starts at the location + of the inserted node (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: none +Dependencies: printf, rotateLeft, rotateRight, swapColors, + displayTreeStructure, displayDivider +*/ +void resolveRBT( RedBlackNodeType **treeRoot, RedBlackNodeType *wkgPtr ); + +/* +Name: rotateLeft +Process: "rotates" nodes to the left by resetting pointers + to related nodes +Function input/parameters: old and new top node pointers (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: pointer to new top node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +RedBlackNodeType *rotateLeft( RedBlackNodeType *newTopPtr, + RedBlackNodeType *oldTopPtr ); + +/* +Name: rotateRight +Process: "rotates" nodes to the right by resetting pointers + to related nodes +Function input/parameters: old and new top node pointers (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: pointer to new top node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +RedBlackNodeType *rotateRight( RedBlackNodeType *newTopPtr, + RedBlackNodeType *oldTopPtr ); + +/* +Name: swapColors +Process: swaps or exchanges colors between two nodes +Function input/parameters: pointers to two nodes (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: updated pointers to two nodes (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +void swapColors( RedBlackNodeType *one, RedBlackNodeType *other ); + + +//////////////////////////////////////////////////////////////////////////////// +// No student coding below this point +//////////////////////////////////////////////////////////////////////////////// + +/* +Name: displayAtTreeLevel +Process: displays one horizontal "level" of a tree using text graphics + with appropriate spacing and appropriate number of nodes +Function input/parameters: recursive working node (RedBlackNodeType *), + node height, display level, working level (int), + row start flag (bool), + control code for either data or color +Function output/parameters: none +Function output/returned: updated row start flag (bool *) +Device input/---: none +Device output/---: none +Dependencies: displayValue, displayEmptyNodeSpaces +*/ +void displayAtTreeLevel( RedBlackNodeType *workingNode, int nodeHeight, + int displayLevel, int workingLevel, + bool *rowStartFlag, ControlCodes ctrlCode ); + +/* +Name: displayChars +Process: recursively displays a specified number of specified characters +Function input/parameters: number of characters (int), + character to be displayed (char) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: characters displayed as specified +Dependencies: printf +*/ +void displayChars( int numChars, char outChar ); + +/* +Name: displayDivider +Process: displays divider of correct length for tree + using either THICK_DIVIDER or THIN_DIVIDER + depending on the control code, + adds one endline to thick divider, two to thin for spacing +Function input/parameters: number of characters (int), + character to be displayed (char) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: characters displayed as specified +Dependencies: printf +*/ +void displayDivider( RedBlackNodeType *rootPtr, char dividerChar ); + +/* +Name: displayEmptyNodeSpaces +Process: displays the appropriate number of dashes for a given level + for null nodes, can display either dashes or 'B's +Function input/parameters: node height, display level, working level (int) + pointer to row start flag (bool *), + control code for either data or color +Function output/parameters: none +Function output/returned: updated row start flag (bool *) +Device input/---: none +Device output/---: characters displayed as specified +Dependencies: toPower, displayValue +*/ +void displayEmptyNodeSpaces( int nodeHeight, + int displayLevel, int workingLevel, + bool *rowStartFlag, ControlCodes ctrlCode ); + +/* +Name: displayTreeStructure +Process: repeatedly calls other function to display + the structure of an RB tree, can display either dashes or 'B's, + displays error message if empty tree +Function input/parameters: tree root pointer (RedBlackNodeType *), + control code for either data or color +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: characters displayed as specified +Dependencies: findTreeHeight, displayAtTreeLevel, printf +*/ +void displayTreeStructure( RedBlackNodeType *rbTreeRoot, + ControlCodes ctrlCode ); + +/* +Name: displayValue +Process: displays a tree character value or color letter (R/B) + after a calculated set of leading spaces +Function input/parameters: character data (char), + node height, working level (int), + pointer to row start flag (bool *) +Function output/parameters: updated row start flag (bool *) +Function output/returned: none +Device input/---: none +Device output/---: character displayed as specified +Dependencies: toPower, displayChars, printf +*/ +void displayValue( char data, int nodeHeight, + int workingLevel, bool *rowStartFlag ); + +/* +Name: getMax +Process: finds the maximum between two values, returns +Function input/parameters: two values (int) +Function output/parameters: none +Function output/returned: maximum of two values (int) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +int getMax( int one, int other ); + +/* +Name: toPower +Process: recursively calculates a base to exponent value + for positive integer exponents +Function input/parameters: base, exponent (int) +Function output/parameters: none +Function output/returned: calculated value (int) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +int toPower( int base, int exponent ); + +#endif //// RED_BLACK_TREE_UTILITY_H diff --git a/PA08-1101/RightRight_SampleRun.txt b/PA08-1101/RightRight_SampleRun.txt new file mode 100644 index 0000000..50bf9fc --- /dev/null +++ b/PA08-1101/RightRight_SampleRun.txt @@ -0,0 +1,254 @@ +Red Black Tree Test Program +=========================== + +Inserting G and resolving + - Root color set to black + +Inserting H and resolving + + B + B R + B B +-------- + + G + - H + - - +======== + +Inserting I and resolving + - Parent is red + - Uncle is black + - Right Right Case + - Rotate Left from right side of grandparent + - Swap grandparent/parent colors + + B + R R + B B B B +-------- + + H + G I + - - - - +======== + +Inserting J and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + - Root color set to black + + B + B B + B B B R + B B +---------------- + + H + G I + - - - J + - - +================ + + B + B B + B B B R + B B +---------------- + + H + G I + - - - J + - - +================ + +Inserting K and resolving + - Parent is red + - Uncle is black + - Right Right Case + - Rotate Left from right side of grandparent + - Swap grandparent/parent colors + + B + B B + B B R R + B B B B +---------------- + + H + G J + - - I K + - - - - +================ + +Inserting F and resolving + + B + B B + R B R R + B B B B B B +---------------- + + H + G J + F - I K + - - - - - - +================ + +Inserting E and resolving + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + B B + R R R R + B B B B B B B B +---------------- + + H + F J + E G I K + - - - - - - - - +================ + +Inserting D and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + + B + R B + B B R R + R B B B B B B B + B B +-------------------------------- + + H + F J + E G I K + D - - - - - - - + - - +================================ + + B + R B + B B R R + R B B B B B B B + B B +-------------------------------- + + H + F J + E G I K + D - - - - - - - + - - +================================ + +Inserting C and resolving + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + R B + B B R R + R R B B B B B B + B B B B +-------------------------------- + + H + F J + D G I K + C E - - - - - - + - - - - +================================ + +Inserting B and resolving + - Parent is red + - Uncle is red + - Grandparent set to red + - Uncle set to black + - Parent set to black + - Resolving Grandparent + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + R R + B B B B + R B B B B B R R + B B B B B B +-------------------------------- + + F + D H + C E G J + B - - - - - I K + - - - - - - +================================ + + B + R R + B B B B + R B B B B B R R + B B B B B B +-------------------------------- + + F + D H + C E G J + B - - - - - I K + - - - - - - +================================ + +Inserting A and resolving + - Parent is red + - Uncle is black + - Left Left Case + - Rotate Right from left side of grandparent + - Swap grandparent/parent colors + + B + R R + B B B B + R R B B B B R R + B B B B B B B B +-------------------------------- + + F + D H + B E G J + A C - - - - I K + - - - - - - - - +================================ + +Inorder : A/R; B/B; C/R; D/R; E/B; F/B; G/B; H/R; I/R; J/B; K/R + +Postorder: A/R; C/R; B/B; E/B; D/R; G/B; I/R; K/R; J/B; H/R; F/B + +Preorder : F/B; D/R; B/B; A/R; C/R; E/B; H/R; G/B; J/B; I/R; K/R + +Copying Tree + F + D H + B E G J + A C - - - - I K + - - - - - - - - + +End Program + diff --git a/PA08-1101/StandardConstants.h b/PA08-1101/StandardConstants.h new file mode 100644 index 0000000..e536c24 --- /dev/null +++ b/PA08-1101/StandardConstants.h @@ -0,0 +1,73 @@ +// 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 '-' + +// highest printable character +#define HIGHEST_PRINTABLE_CHAR '~' + +// constant for huge string length +#define HUGE_STR_LEN 256 + +// lowest printable character +#define LOWEST_PRINTABLE_CHAR ' ' + +// 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 NEWLINE_CHAR '\n' + +// first non-printable above ASCII +#define DELETE_KEY 127 + +// constant for end of c-string null character +#define NULL_CHAR '\0' + +// columns found in grade sheet before grading columns +#define NUM_BASE_COLS 5 + +// constant for number of grading frequency bins +#define NUM_FREQUENCY_BINS 10 + +//Constant for printing a pipe +#define PIPE '|' + +//Constant for a period +#define PERIOD '.' + +//Constant for PRECISION, 2 digits +#define PRECISION_2 2 + +//Constant for PRECISION, 4 digits +#define PRECISION_4 4 + +// constant for space character +#define SPACE ' ' + +// constant for standard string length +#define STD_STR_LEN 64 + +// constant for smallest string length +#define TINY_STR_LEN 16 + +#endif // STANDARD_CONSTANTS