This advanced C programming project showcases mastery of complex programming concepts, including data manipulation, pointer arithmetic, file handling, and dynamic memory management. The project consists of three intricately linked programs, each designed to demonstrate practical problem-solving and efficient algorithm design in C.
To make it easy for you to run the code, I’ve created an account on Online GDB, a convenient online compiler. Below are the login details:
- Email: egarrett055@gmail.com
- Password: tempUser
Follow these steps to run the program:
- Click here to open the project.
- Enter the login credentials provided above (email and password).
- On the left side of the page, click on "My Projects".
- Find and select the project titled "Dynamic Data Manipulator".
- Click on the "Dynamic Data Manipulator" project to open it.
- Inside the project, locate and click the file named "main.c".
- Click the "Run" button to execute the program.
- If prompted, select "C" from the "Language" dropdown near the top of the screen to proceed.
- The program’s output will appear at the bottom of the screen, allowing you to experience the results of my work.
Enjoy exploring the program!
Table of Contents 📖
The Dynamic Data Manipulator is a set of three advanced programs that demonstrate a wide range of C programming skills:
- Word Frequency Analyzer: Extracts and counts word occurrences in large text files, sorting them lexicographically.
- Linked List Manipulator: Implements and manipulates dynamic linked lists with operations such as insertion, deletion, and traversal.
- Matrix Processor: Performs complex matrix operations, showcasing array manipulation and numerical analysis.
- Trie-Based Pokémon Search: Utilizes a Trie data structure to efficiently store and search Pokémon names. Custom character indexing optimizes memory usage and speeds up retrieval, ensuring fast performance with large datasets.
- Efficiency and Scalability: Optimized algorithms and memory management ensure the programs handle large datasets with minimal overhead.
- Structured Design: Adhering to clean code principles, each module emphasizes readability and reusability.
- Error Handling and Robustness: Built-in mechanisms for input validation, memory safety, and runtime error detection ensure the programs are reliable.
This structure defines the attributes of an individual Pokémon. It contains:
pokemonNum
: The Pokémon's unique number in the Pokédex.catchPercentage
: The percentage chance of catching the Pokémon.name
: The name of the Pokémon (e.g., "Pikachu").type
: The type(s) of the Pokémon (e.g., "Electric").region
: The region from which the Pokémon hails (e.g., "Kanto").dexEntry
: A description of the Pokémon from the Pokédex.data
: A pointer to thePokemonStatus
structure that stores the Pokémon's status (caught or seen).next
: A pointer to the next Pokémon in the linked list of caught Pokémon.
This structure defines the status of a Pokémon, providing details about its visibility, attributes, and individual values:
caught
: The number of times the Pokémon has been caught.seen
: The number of times the Pokémon has been seen by the player.attackIV
: The individual value (IV) representing the Pokémon's attack potential.defenseIV
: The individual value (IV) representing the Pokémon's defense potential.staminaIV
: The individual value (IV) representing the Pokémon's stamina potential.percentIV
: A calculated percentage representing the overall strength of the Pokémon based on its IVs.
This structure contains function pointers responsible for managing and manipulating the linked list of Pokémon. Each function pointer performs a specific operation on the linked list:
addPtr
: A function pointer pointing to theadd
function, which adds a new Pokémon to the linked list.sortPtr
: A function pointer pointing to thesort
function, which sorts the Pokémon in the linked list.reversePtr
: A function pointer pointing to thereverse
function, which reverses the order of Pokémon in the linked list.deleteNodesPtr
: A function pointer pointing to thedeleteNodes
function, which deletes nodes from the linked list.swapPtr
: A function pointer pointing to theswap
function, which swaps two Pokémon within the linked list.
This structure contains function pointers responsible for facilitating menu operations and calling various functions when the user interacts with the menu or exits the program. Each function pointer represents a specific operation or menu functionality:
menuPtr
: A function pointer pointing to themenu
function, which displays the main menu to the user and handles their selections.huntPtr
: A function pointer pointing to thehunt
function, which manages Pokémon hunting operations, allowing the user to search for and encounter Pokémon.pokemonCaughtPtr
: A function pointer pointing to thesortMenu
function, which handles operations related to sorting Pokémon caught by the user.statsPtr
: A function pointer pointing to thestats
function, which displays statistical information such as total Pokémon seen and caught.inventoryPtr
: A function pointer pointing to theinventory
function, which shows the user's inventory details, including resources like Poké Balls.displayPokePtr
: A function pointer pointing to thedisplayPoke
function, which displays detailed information about individual Pokémon.writeToFilePtr
: A function pointer pointing to thewriteToFile
function, which saves the Pokémon data to a file for future reference.
This structure defines a Trie for storing characters within a string efficiently. It contains:
children[ALPHABET_SIZE]
: An array of pointers to child Tries, where each child corresponds to a character in the string.isEndOfWord
: A boolean indicating whether the current node marks the end of a word.index
: An integer used to store the index of the word, potentially for later reference or retrieval.
This structure defines a Trie Manager for efficient Pokémon searching and insertion in the trie. It contains:
getNodePtr()
: A function pointer that initializes and returns a pointer to a new Trie node.getCharIndexPtr()
: A function pointer that returns the index corresponding to a character within the trie.insertPtr()
: A function pointer that inserts a string into the trie, associating it with an index and using the TrieManager for management.searchPtr()
: A function pointer that searches the trie for a given string and returns a boolean indicating if the string exists.freeTriePtr()
: A function pointer that frees all dynamically allocated memory for the trie nodes.
Description: This function initializes an instance of the ListManager
structure by assigning function pointers to the appropriate functions that will manipulate the linked list of Pokémon. It sets up the necessary functions for adding, sorting, reversing, deleting nodes, and swapping Pokémon within the list.
Parameters:
struct ListManager *manager
: A pointer to aListManager
structure that will be initialized.
Returns: Nothing (void).
Description: This function initializes an instance of the MenuManager
structure by assigning function pointers to the appropriate menu functions. It sets up the necessary functions for navigating the Pokémon game menu, managing hunting, displaying Pokémon caught, stats, inventory, and writing data to a file.
Parameters:
struct MenuManager *manager
: A pointer to aMenuManager
structure that will be initialized.
Returns: Nothing (void).
Description: This function initializes an instance of the TrieManager
structure by assigning function pointers for creating, searching, inserting, and freeing a trie from memory. It sets up the necessary functions for trie management.
Parameters:
struct TrieManager *manager
: A pointer to theTrieManager
instance to be initialized.
Returns: Nothing (void).
Description: This function creates a new root node for the trie. It dynamically allocates memory for a Trie
structure and initializes its fields, including setting isEndOfWord
to false, index
to -1, and setting all child nodes to NULL
.
Returns: A pointer to the newly created Trie
node.
Description: This function takes a character pointer and returns the corresponding index in the trie based on the character pointed to by ptr
. It handles both uppercase and lowercase letters, as well as special characters like apostrophes, periods, and hyphens.
Parameters:
const char *ptr
: A pointer to a character whose index in the trie is to be determined.
Returns: An integer representing the index of the character in the trie.
void insert(struct Trie *root, const char *string, const int *number, const struct TrieManager *manager)
Description: This function inserts a new string into the trie, creating new nodes as needed. It iterates through the string, adding characters to the trie, and marks the last node of the string as the end of a word with the associated index.
Parameters:
struct Trie *root
: A pointer to the root node of the trie.const char *string
: A pointer to the string to be inserted into the trie.const int *number
: A pointer to the integer value to be stored at the last node of the inserted string.const struct TrieManager *manager
: A pointer to theTrieManager
instance, which provides necessary function pointers for trie operations.
Returns: Nothing (void).
Description: This function searches the trie for a given string. It traverses the trie based on the characters in the string, checking if each character exists in the trie. If the string is found, it returns true and stores the associated index in number
.
Parameters:
struct Trie *root
: A pointer to the root node of the trie.const char *string
: A pointer to the string to be searched for in the trie.int *number
: A pointer to store the index associated with the string if found.const struct TrieManager *manager
: A pointer to theTrieManager
instance, which provides necessary function pointers for trie operations.
Returns: A boolean indicating whether the string exists in the trie. Returns true if found, false otherwise.
Description: This function removes any new-line characters from the given string and replaces them with a null character (\0
). This is useful for cleaning up user input or file data that may have trailing new-line characters.
Parameters:
char *name
: A pointer to the string from which the new-line characters will be removed.
Returns: Nothing (void).
Description: This function checks whether the provided region string is a valid Pokémon region. It allows the user to specify a region in the game, ensuring that only valid regions are selected.
Parameters:
char *region
: A pointer to a string containing the region input by the user.
Returns: A boolean value: true
if the region is valid, false
otherwise.
Description: This function prints a neat and organized menu that provides the player with different options to interact with the Pokémon game. It serves as the starting point for navigating through various gameplay features.
Parameters: None
Returns: Nothing (void).
Description: This function captures the player's input from the menu selection and processes it into a friendly format. It helps ensure that user input is clean and valid for further processing in the game.
Parameters:
char *selection
: A pointer to a character array where the formatted input will be stored.
Returns: Nothing (void).
void hunt(char *region, struct Pokemon *pokemons, const int *size, void (*balls) (const int *, const int *, const int *), int *pokeBalls, int *greatBalls, int *ultraBalls, int *caught, int *seen, struct Pokemon **head, const struct ListManager *manager)
Description: This function facilitates the Hunt menu option for catching Pokémon. It handles the process of encountering Pokémon from a specific region, selecting a Poké Ball, and attempting to catch the Pokémon. The function uses a random number generator to determine the encounter and Pokémon statistics, and it updates the player's Pokémon collection based on the outcome of each catch attempt.
Parameters:
char *region
: A pointer to a string containing the region where the Pokémon is encountered (e.g., "Kanto", "Johto").struct Pokemon *pokemons
: A pointer to an array of Pokémon structures, where each Pokémon has specific data such as catch percentage and individual values.const int *size
: A pointer to the total number of Pokémon in the game.void (*balls) (const int *, const int *, const int *)
: A function pointer to display the number of Poké Balls, Great Balls, and Ultra Balls the player has.int *pokeBalls
,int *greatBalls
,int *ultraBalls
: Pointers to integers representing the number of each type of Poké Ball the player has left.int *caught
,int *seen
: Pointers to integers tracking the number of Pokémon caught and seen.struct Pokemon **head
: A pointer to the head of the linked list of caught Pokémon.const struct ListManager *manager
: A pointer to a ListManager instance containing function pointers for manipulating the linked list of Pokémon.
Returns: Nothing (void).
void huntHelper(int *catchNum, int *balls, struct Pokemon *pokemons, const int *index, int *caught, int *seen, struct Pokemon **head, const struct ListManager *manager)
Description: This function simulates the process of attempting to catch a Pokémon using an Ultra Ball. It checks whether the Pokémon can be caught based on a random number and the Pokémon's catch percentage, accounting for the increased chances provided by the Ultra Ball. Depending on the result, it either calls a function to handle the successful catch or the Pokémon fleeing.
Parameters:
int *catchNum
: A pointer to an integer representing a randomly generated number used to determine the success of catching the Pokémon.int *balls
: A pointer to the integer representing the number of Ultra Balls the player has, which is decremented after each use.struct Pokemon *pokemons
: A pointer to an array of Pokémon structures, where each Pokémon has attributes like catch percentage.const int *index
: A pointer to the index of the current Pokémon being encountered.int *caught
: A pointer to an integer tracking the number of Pokémon successfully caught.int *seen
: A pointer to an integer tracking the number of Pokémon seen by the player.struct Pokemon **head
: A pointer to the head of the linked list of caught Pokémon.const struct ListManager *manager
: A pointer to aListManager
instance containing functions for manipulating the linked list of caught Pokémon.
Returns: Nothing (void).
Description: This function displays the player's current inventory of Poké Balls, giving information about how many of each type of ball the player possesses. It helps keep track of the player's available resources for catching Pokémon.
Parameters:
const int *standardBalls
: A pointer to the number of standard Poké Balls.const int *greatBalls
: A pointer to the number of Great Balls.const int *ultraBalls
: A pointer to the number of Ultra Balls.
Returns: Nothing (void).
Description: This function adds a newly caught Pokémon to the end of the player's linked list of Pokémon. It allows the player to build their collection by adding new entries to the list.
Parameters:
struct Pokemon **pokemonList
: A pointer to the list of Pokémon to which the new Pokémon will be added.const struct Pokemon *newPokemon
: A pointer to the Pokémon structure representing the new Pokémon being added.const int *pokemonCount
: A pointer to the total count of Pokémon caught by the player.
Returns: A pointer to the updated list of Pokémon.
struct Pokemon *pokeCaught(struct Pokemon *pokemons, const int *random, int *caught, int *seen, struct Pokemon **head, const struct ListManager *manager)
Description: This function facilitates the process of the user successfully catching a Pokémon. It prints a congratulatory message, updates the caught and seen counters for the Pokémon, and adds the caught Pokémon to the linked list of caught Pokémon.
Parameters:
struct Pokemon *pokemons
: A pointer to an array of Pokémon structures, where each Pokémon has specific data such as name, caught, and seen counters.const int *random
: A pointer to the index of the Pokémon that has been successfully caught.int *caught
,int *seen
: Pointers to integers tracking the number of Pokémon caught and seen by the user.struct Pokemon **head
: A pointer to the head of the linked list of caught Pokémon.const struct ListManager *manager
: A pointer to a ListManager instance containing function pointers for manipulating the linked list of Pokémon.
Returns: The updated head of the linked list of caught Pokémon.
Description: This function handles the scenario when a Pokémon runs away from the user's attempt to catch it. It prints a message indicating the Pokémon fled and increments the 'seen' counter for the Pokémon.
Parameters:
struct Pokemon *pokemons
: A pointer to an array of Pokémon structures representing the available Pokémon.const int *random
: A pointer to the index of the randomly selected Pokémon that ran away.int *seen
: A pointer to the total number of Pokémon seen.
Returns: Nothing (void).
Description: This function displays the list of Pokémon that the user has caught and allows the user to select between viewing detailed information about the caught Pokémon or just listing their names. It also provides an option to exit the menu.
Parameters:
const struct Pokemon *head
: A pointer to the head of the linked list of caught Pokémon.int *selection
: A pointer to the user's selection for how they wish to view their caught Pokémon (view details, list caught Pokémon, or exit).
Returns: Nothing (void).
Description: This function prints the user's statistics, including the number of Pokémon caught and seen, and calculates the catch rate if more than one Pokémon has been caught.
Parameters:
const int *caught
: A pointer to the total number of Pokémon caught by the user.const int *seen
: A pointer to the total number of Pokémon seen by the user.
Returns: Nothing (void).
Description: This function displays the user's inventory of Poké Balls, including Poke Balls, Great Balls, and Ultra Balls. The inventory is presented in a neat, tabular format.
Parameters:
const int *pokeBall
: A pointer to the number of Poké Balls the user has.const int *greatBall
: A pointer to the number of Great Balls the user has.const int *ultraBall
: A pointer to the number of Ultra Balls the user has.
Returns: Nothing (void).
Description: This function displays detailed information about a specific Pokémon, identified by the index passed to it. It prints the Pokémon's name, type, and Dex entry.
Parameters:
const struct Pokemon *pokemons
: A pointer to the array of Pokémon.const int *index
: A pointer to the index of the Pokémon whose information is to be displayed.
Returns: Nothing (void).
Description: This function displays a menu that allows the user to choose how they would like to sort the Pokémon list. The menu offers various sorting options, including lexicographical sorting, sorting by type, and sorting by Pokémon number.
Parameters: None
Returns: The user's sorting selection as an integer (1 to 6).
Description: This function sorts the linked list of Pokémon based on the user's selection from the sorting menu. It allows sorting by name (lexicographically ascending or descending), type, and Pokémon number, as well as reversing the list. It utilizes a helper function for swapping nodes in the linked list and updates the head pointer when necessary.
Parameters:
struct Pokemon *head
: A pointer to the head of the linked list of Pokémon.const struct ListManager *manager
: A pointer to a ListManager structure responsible for managing list operations such as swapping and reversing nodes.
Returns: The head pointer of the sorted (or reversed) linked list.
Description: This function traverses the linked list of Pokémon and frees the dynamically allocated memory for each node. After all nodes are freed, it returns NULL
to indicate that the list is empty.
Parameters:
struct Pokemon *head
: A pointer to the head of the linked list of Pokémon.
Returns: NULL
, indicating that the list has been deleted.
Description: This function swaps the data between two nodes in the linked list. It facilitates sorting by swapping the Pokémon information between the nodes pointed to by ptr
and ptr2
.
Parameters:
struct Pokemon *ptr
: A pointer to the first node in the linked list to swap.struct Pokemon *ptr2
: A pointer to the second node in the linked list to swap.struct Pokemon *head
: A pointer to the head of the linked list, though it is not used directly in this function.
Returns: Nothing (void).
Description: This function reverses the order of nodes in the doubly linked list of Pokémon. It copies the Pokémon data to an array and then updates the list in reverse order by swapping the data between the nodes.
Parameters:
struct Pokemon *head
: A pointer to the head of the linked list of Pokémon.const struct ListManager *manager
: A pointer to the ListManager structure responsible for managing list operations.
Returns: The head pointer of the reversed linked list.
Description: This function writes the details of the Pokémon in the linked list to a file called pokemons.txt
. The file contains a header, followed by the Pokémon data in a table format, and ends with a footer.
Parameters:
const struct Pokemon *head
: A pointer to the head of the linked list of Pokémon.
Returns: Nothing (void).
Description: This function recursively frees the dynamically allocated memory used to create a trie structure. It starts by checking if the current node is NULL, and if not, it traverses through each child node, recursively freeing memory for all descendant nodes before freeing the current node itself.
Parameters:
struct Trie *trie
: A pointer to the root of the trie structure to be freed. The function will recursively free all nodes starting from this root.
Returns: Nothing (void).
1. Compile the Program:
2. Run the Program: