#include "StateUtilities.h" // local constants const int NAME_BLOCK_SIZE = 16; const int POPULATION_BLOCK_SIZE = 12; const int GROWTH_BLOCK_SIZE = 10; // missing constants from assignment file const int ITEM_BLOCK_SIZE = 6; const int MAJORITY_BLOCK_SIZE = 10; const char EQUALS = '='; const char PLUS = '+'; // functions /* Name: addElementFromData Process: adds all individual data values to StateDataType array if capacity has not been exceeded, returns true upon success, false otherwise Function input/parameters: data array (StateDataType *), size (int), capacity (int), state name (const char *), state population (int), state growth (double), state political majority (char) Function output/parameters: updated data array (StateDataType *), updated size (int *) Function output/returned: Boolean result of operation as specified Device input/---: none Device output/---: none Dependencies: as needed, including strcpy */ bool addElementFromData( StateDataType *stateArr, int *size, int capacity, const char *stateName, int statePop, double stateGrowth, char politicalMajority ) { // check to see if the size will go over the capacity if(*size <= capacity) { // put in the data to the array // array[*size] = parameter stateArr[*size].population = statePop; stateArr[*size].growth = stateGrowth; stateArr[*size].majority = politicalMajority; // string is a little different. // use strcpy(array[*size].name, stateName) strcpy(stateArr[*size].name, stateName); // increment size (*size = *size + 1) *size = *size + 1; // return true return true; } // otherwise, return false. return false; } /* Name: addElementFromElement Process: adds data from element to StateDataType array, uses supporting function Function input/parameters: data array (StateDataType *), size and capacity (int), source element (const StateDataType) Function output/parameters: updated data array (StateDataType *), updated size (int *) Function output/returned: Boolean result of operation as specified Device input/---: none Device output/---: none Dependencies: addElementFromData - function uses one code statement */ bool addElementFromElement( StateDataType *stateArr, int *size, int capacity, const StateDataType state ) { return addElementFromData(stateArr, size, capacity, state.name, state.population, state.growth, state.majority); } /* Name: clearStateArray Process: deallocates dynamically allocated array from memory Function input/parameters: data array (StateDataType *) Function output/parameters: none Function output/returned: NULL Device input/---: none Device output/---: none Dependencies: as needed, including free */ StateDataType *clearStateArray( StateDataType *array ) { // use free to deallocate the array free(array); return NULL; } /* Name: copyArray Process: copies state data elements from one array to another Function input/parameters: source array (const StateDataType *), size (int) Function output/parameters: pointer to destination array (StateDataType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: as needed */ void copyArray( StateDataType *dest, const StateDataType *src, int srcSize ) { // use a for loop to iterate through source array (start at zero, go to srcSize) // copy each element from the array to the new array. // uses deepCopy to do this. // no return, void } /* Name: createStateArray Process: dynamically allocates array memory Function input/parameters: initial capacity (int) Function output/parameters: none Function output/returned: pointer to newly created array (StateDataType *) Device input/---: none Device output/---: none Dependencies: as needed, including function malloc and keyword sizeof */ StateDataType *createStateArray( int initialCapacity ) { // define variables (integer, StateDataType) StateDataType *stateArray; // use malloc to dynamically allocate the array, // use the initialCapacity as the size to multiply by. stateArray = malloc(sizeof(StateDataType) * initialCapacity); // return the pointer to the array. return stateArray; } /* Name: deepCopy Process: copies all individual values from StateDataType source to StateDataType destination Function input/parameters: source element (const StateDataType) Function output/parameters: pointer to destination value (StateDataType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: as needed, including strcpy */ void deepCopy( StateDataType *dest, const StateDataType src ) { // *dest.population = src.population (for each piece) dest->population = src.population; dest->growth = src.growth; dest->majority = src.majority; // strcpy for the string // strcpy(*dest.name, src.name) strcpy(dest->name, src.name); // no return, void } /* Name: displayData Process: displays element data in array as table if array is not empty, otherwise displays "Data not found - Display aborted", allows for subtitle to be added to "Display Data - " Function input/parameters: state data array (const StateDataType *), size (int), subtitle (const char *) Function output/parameters: none Function output/returned: none Device input/---: none Device output/monitor: data displayed as specified Dependencies: as needed */ void displayData( const StateDataType *array, int size, const char *subTitle ) { int countStates; // iterate through array to size, check if zero. if(size != 0) { printEndline(); printString(subTitle); printEndline(); // create a table // print PIPE character printCharacter(PIPE); // print ITEM justified center printStringJustified("Item", ITEM_BLOCK_SIZE, "CENTER"); // print PIPE character printCharacter(PIPE); // print STATE NAME justified center printStringJustified("State Name", NAME_BLOCK_SIZE, "CENTER"); // print PIPE character printCharacter(PIPE); // print POPULATION justified center printStringJustified("Population", POPULATION_BLOCK_SIZE, "CENTER"); // print PIPE character printCharacter(PIPE); // print GROWTH justified center printStringJustified("Growth", GROWTH_BLOCK_SIZE, "CENTER"); // print PIPE character printCharacter(PIPE); // print MAJORITY justified center printStringJustified("Majority", MAJORITY_BLOCK_SIZE, "CENTER"); // print PIPE character printCharacter(PIPE); // print new line printEndline(); // printing the top border piece // print PIPE character printCharacter(PIPE); // print amount of = for ITEM printCharacters(ITEM_BLOCK_SIZE, EQUALS); // print PLUS (needs constant) character printCharacter(PLUS); // print amount of = for STATE NAME printCharacters(NAME_BLOCK_SIZE, EQUALS); // print PLUS character printCharacter(PLUS); // print amount of = for POPULATION printCharacters(POPULATION_BLOCK_SIZE, EQUALS); // print PLUS character printCharacter(PLUS); // print amount of = for GROWTH printCharacters(GROWTH_BLOCK_SIZE, EQUALS); // print PLUS character printCharacter(PLUS); // print amount of = for MAJORITY printCharacters(MAJORITY_BLOCK_SIZE, EQUALS); // print PIPE character printCharacter(PIPE); // print new line printEndline(); for(countStates = 0; countStates <= size; countStates++) { // use the constants to format the table // print PIPE character printCharacter(PIPE); // print item justified right (size) printIntegerJustified(countStates + 1, ITEM_BLOCK_SIZE, "RIGHT"); // print PIPE character printCharacter(PIPE); // print state name justified left printStringJustified(array[countStates].name, NAME_BLOCK_SIZE, "LEFT"); // print PIPE character printCharacter(PIPE); // print population justified right printIntegerJustified(array[countStates].population, POPULATION_BLOCK_SIZE, "RIGHT"); // print PIPE character printCharacter(PIPE); // print growth justified right, need a % sign too. (requires some math trickery to make work) printDoubleJustified(array[countStates].growth, PRECISION_2, GROWTH_BLOCK_SIZE - 2, "RIGHT"); printCharacter('%'); printCharacter(SPACE); // print PIPE character printCharacter(PIPE); // print majority justified center, also requires some math trickery to make work printCharacters((MAJORITY_BLOCK_SIZE - 1) / 2, SPACE); printCharacter(SPACE); printCharacter(array[countStates].majority); printCharacters((MAJORITY_BLOCK_SIZE - 1) / 2, SPACE); // print PIPE character printCharacter(PIPE); // print endline printEndline(); // printing for the spacer lines // print PIPE character printCharacter(PIPE); // print amount of DASH for item printCharacters(ITEM_BLOCK_SIZE, DASH); // print PLUS character printCharacter(PLUS); // print amount of DASH for state name printCharacters(NAME_BLOCK_SIZE, DASH); // print PLUS character printCharacter(PLUS); // print amount of DASH for population printCharacters(POPULATION_BLOCK_SIZE, DASH); // print PLUS character printCharacter(PLUS); // print amount of DASH for growth printCharacters(GROWTH_BLOCK_SIZE, DASH); // print PLUS character printCharacter(PLUS); // print amount of DASH for majority printCharacters(MAJORITY_BLOCK_SIZE, DASH); // print PIPE character printCharacter(PIPE); /* testing */ printf("Iteration: %d", countStates); // print endline printEndline(); } } else { //print out "Data not found - Display aborted". printString("Data not found - Display aborted"); printEndline(); } // no return, void } /* Name: findStateByName Process: finds element value in array by state name if it exists in the array, saves data in return parameter and returns true, otherwise sets data in return parameter to empty and returns false Function input/parameters: state data array (const StateDataType *), size (int), search value (const StateDataType) Function output/parameters: value if found as return parameter, otherwise, return parameter set to empty (StateDataType *) Function output/returned: Boolean result of operation Device input/---: none Device output/---: none Dependencies: as needed */ bool findStateByName( StateDataType *foundElement, const StateDataType *array, int size, const StateDataType searchValue ) { // iterate through array // check to see if the state name is found (use searchValue) // copy the element out of the array, put in foundElement // return true // otherwise, return false return false; } /* Name: removeStateByName Process: searches for element, if found, sets data into return parameter, shifts all remaining data down, and returns true, otherwise sets data in return parameter to empty and returns false Function input/parameters: state data array (StateDataType *), size (int), search value (const StateDataType) Function output/parameters: updated state data array (StateDataType *), value if found and removed, otherwise, value set to empty (StateDataType *), updated size (int *) Function output/returned: Boolean result of operation as specified Device input/---: none Device output/---: none Dependencies: as needed */ bool removeStateByName( StateDataType *removedElement, StateDataType *array, int *size, const StateDataType searchVal ) { // iterate through array // use the findStateByName to search // remove the element by copying the next element into last slot until end // reduce the size by one // return true // otherwise, return false return NULL; } /* Name: runBubbleSortByName Process: sorts state data by name using bubble sort algorithm Function input/parameters: state data array (StateDataType *), size (int) Function output/parameters: updated state data array (StateDataType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: as needed */ void runBubbleSortByName( StateDataType *array, int size ) { // start iterator at size - 2? // iterate through iterator // check the current index vs the next one. // if current > next, swap. // no return, void } /* Name: runInsertionSortByPopulation Process: sorts state data by population using insertion sort algorithm Function input/parameters: state data array (StateDataType *), size (int) Function output/parameters: updated state data array (StateDataType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: as needed, swap may not be used */ void runInsertionSortByPopulation( StateDataType *array, int size ) { // no return, void } /* Name: runSelectionSortByGrowth Process: sorts state data by growth using selection sort algorithm Function input/parameters: state data array (StateDataType *), size (int) Function output/parameters: updated state data array (StateDataType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: as needed */ void runSelectionSortByGrowth( StateDataType *array, int size ) { // no return, void } /* Name: setEmptyElementData Process: sets state data type to empty or default values, name to empty string, population and growth to zero, and majority to 'x' Function input/parameters: none Function output/parameters: state data value (StateDataType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: none */ void setEmptyElementData( StateDataType *element ) { // set the element's name to "" strcpy(element->name, ""); // set the element's population and growth to 0 element->population = 0; element->growth = 0.0; // set the element's majority to 'x' element->majority = 'x'; // no return, void } /* Name: showTitle Process: displays program title with thick underline, "Data Management with N-Squared Sorting" Function input/parameters: none Function output/parameters: none Function output/returned: none Device input/---: none Device output/monitor: displays title as specified Dependencies: as needed */ void showTitle() { // use console io utilities to display the string printString("Data Management with N-Squared Sorting"); // print endline printEndline(); // use console io utilities to display 38 '=' printCharacters(38, '='); // print an endline printEndline(); // no return, void } /* Name: swapElements Process: swaps state data elements within an array Function input/parameters: given array (StateDataType *), left and right indices to be swapped (int) Function output/parameters: updated array with swapped values (StateDataType *) Function output/returned: none Device input/---: none Device output/---: none Dependencies: as needed */ void swapElements( StateDataType *array, int leftIndex, int rightIndex ) { // create StateDataType temp to store swapped element // use deepCopy to copy out swapped element // use deepCopy to move the other element, // use deepCopy to copy the temp element to the other element // updated the array // no return, void } /* Name: uploadStateData Process: uploads data from given file to state data array, ignores first (title) line in .csv file, then captures comma-delimited state name, population, growth, and political majority data on each row, returns number of items found; stops uploading process if array is full Function input/parameters: capacity (int) and file name (const char *) Function output/parameters: updated array with uploaded values (StateDataType *) Function output/returned: number of items uploaded (int) Device input/HD: data uploaded from text file as specified Device output/---: none Dependencies: as needed */ int uploadStateData( StateDataType *StateDataArray, int capacity, const char *fileName ) { //printf("\nUploading Data?\n"); // setup a counter and other variables int stateCount = 0; StateDataType *stateUpload; bool fileOpenCheck; char currentString[STD_STR_LEN]; int populationUpload; double growthUpload; char majorityUpload; setEmptyElementData(&stateUpload); // open file fileOpenCheck = openInputFile(fileName); //printf("\nOPENS FILE\n"); if(fileOpenCheck) { //printf("\nCHECKED FILE\n"); // read in the four strings/starting line (use readStringToLineEndFromFile) readStringToLineEndFromFile(currentString); // readStringToDelimiterFromFile(COMMA, currentString); // readStringToDelimiterFromFile(COMMA, currentString); // readStringToDelimiterFromFile(COMMA, currentString); // readStringToDelimiterFromFile(COMMA, currentString); while(!checkForEndOfInputFile()) { //printf("\nIN WHILE\n"); // repeat these steps: (use readStringToDelimiterFromFile) // read in the state name, store //printf("\nReadingString\n"); readStringToDelimiterFromFile(COMMA, currentString); //printf("\nReadString\n"); //printf("\nCopy String\n"); strcpy(stateUpload->name, currentString); //printf("\nCopied String\n"); // read in the population, store (cast from string to int) readStringToDelimiterFromFile(COMMA, currentString); // find a way to cast string to int, sscanf might work best. sscanf(currentString, "%d", &populationUpload); stateUpload->population = populationUpload; // read in the growth, store (cast from string to double) readStringToDelimiterFromFile(COMMA, currentString); // find a way to cast string to double, using sscanf. sscanf(currentString, "%lf", &growthUpload); stateUpload->growth = growthUpload * 100; // read in the majority, store readStringToDelimiterFromFile(COMMA, currentString); // get the first character of currentString majorityUpload = currentString[0]; stateUpload->majority = majorityUpload; // use the addElementFromData function to add the data to array addElementFromData(StateDataArray, &stateCount, capacity, stateUpload->name, stateUpload->population, stateUpload->growth, stateUpload->majority); // do until end of the file is reached. } } else { // error out printf("\nThe file you referenced either does not exist, or inadequate file permissions to access.\n"); } // return counter return stateCount; }