This project implements a doubly-linked circular list (MyList) and a transaction sorting utility (transaction.c). The doubly-linked circular list serves as a fundamental data structure for handling transactions, which are read from a file or standard input. The project emphasizes low-level memory management, pointer manipulation, and efficient sorting algorithms to ensure correct functionality.
- stdio.h β Standard I/O operations.
- stdlib.h β Memory allocation and process control.(malloc, free)
- string.h β String manipulation.(strcmp, strcpy)
- time.h β Handling UNIX timestamps (ctime, time)
- ctype.h β Character handling.
- unistd.h β File access control.
- errno.h - Error handling
The MyList is a circular doubly-linked list with an anchor node that simplifies list operations. Unlike a traditional doubly-linked list, the anchor node is always present and is used as a placeholder to manage list boundaries effectively.
-
Anchor Node (
anchor):- A sentinel node that does not store user data.
- Its
nextpointer points to the first real element, and itsprevpointer points to the last real element. - This eliminates edge cases when inserting/removing elements.
-
List Elements (
MyListElem):- Each element stores an object (
obj) representing a transaction. - Contains two pointers:
nextβ Points to the next element in the list.prevβ Points to the previous element in the list.
- Each element stores an object (
-
List Operations:
MyListInit()β Initializes an empty list with only the anchor node.MyListAppend()β Inserts an element at the end of the list.MyListPrepend()β Inserts an element at the beginning of the list.MyListInsertAfter()β Inserts an element after a given node.MyListInsertBefore()β Inserts an element before a given node.MyListUnlink()β Removes a specific element from the list.MyListUnlinkAll()β Clears the entire list.MyListFirst()β Returns the first element in the list.MyListLast()β Returns the last element in the list.MyListNext()β Returns the next element in the list.MyListPrev()β Returns the previous element in the list.
- Avoids null pointer checks at list boundaries.
- Simplifies iteration through the list.
- Efficient insertion/deletion at both ends without special conditions.
This program reads a file containing financial transactions, stores them in a MyList, and sorts them by date.
Each transaction is stored as a line in the input file and consists of: [TYPE] [TIMESTAMP] [AMOUNT] [DESCRIPTION]
[TYPE]:+for credit,-for debit.[TIMESTAMP]: Unix timestamp indicating the transaction time.[AMOUNT]: Decimal value representing the transaction amount.[DESCRIPTION]: A string describing the transaction.
- Ensures the correct number of fields are present.
- Verifies that the timestamp is a valid numeric value.
- Confirms the amount is non-negative and formatted correctly.
- Trims leading/trailing spaces from the description.
- Transactions are stored in a
MyListand sorted by timestamp. - Uses Insertion Sort due to the small dataset size (efficient for up to a few thousand elements).
- Maintains stable sorting so that transactions with identical timestamps retain their input order.
- Developed a custom linked list to manage transactions efficiently.
- Implemented O(1) insertion and deletion operations.
- Ensured the list remains circular by updating
nextandprevpointers.
- Read transaction records from an input file or
stdin. - Tokenized each line using tab-separated fields.
- Checked the validity of timestamps, amounts, and descriptions:
- Timestamps: Must be greater than zero and less than the current time.
- Amounts: Must be formatted correctly with two decimal places.
- Descriptions: Cannot be empty after trimming leading spaces.
- Implemented bubble sort for sorting linked list elements in-place.
- Ensured O(nΒ²) complexity is reasonable given the constraints.
- Handled duplicate timestamps by printing an error and terminating execution.
- Used structured formatting for output:
- Date Field: Converted UNIX timestamps using
ctime(). - Description Field: Truncated to 24 characters max.
- Amount Field: Right-aligned and formatted correctly.
- Balance Field: Updated dynamically while processing transactions.
- Date Field: Converted UNIX timestamps using
- Printed the transaction history as an 80-character-wide table.
- Empty Files: Checked for empty input and printed an error.
- Malformed Transactions: Handled incorrect formats gracefully.
- Extreme Balances: Ensured balances over 10 million were marked as
?,???,???.??.
- Used
gdbto debug segmentation faults and memory allocation errors. - Verified correctness using sample test cases.
- Ensured no memory leaks by freeing allocated structures before exit.
To ensure the correctness and robustness of the implementation, the following testing strategies were employed:
- Doubly-Linked Circular List: Verified insertion, deletion, and traversal.
- Sorting Algorithm: Ensured the transactions are sorted correctly by timestamps.
- Transaction Parsing: Checked handling of various formats and erroneous data.
- Empty Input File: Confirmed that the program properly detects and handles empty files.
- Malformed Transactions: Tested various incorrect formats (e.g., missing fields, invalid timestamps, incorrect amounts).
- Duplicate Timestamps: Ensured that duplicate timestamps trigger an error message and halt execution.
- Valgrind Analysis: Used valgrind to detect memory leaks and invalid memory accesses.
- Pointer Debugging: Ensured proper freeing of allocated memory to avoid segmentation faults.
- Large Dataset Processing: Evaluated performance with a high number of transactions.
- Extreme Values: Tested balances exceeding 10 million to check correct formatting (?,???,???.??).
- High-Frequency Transactions: Ensured sorting and display work efficiently with closely spaced timestamps.
- Used a predefined grading script that runs multiple test cases and validates output using
diff. - Ensured no unexpected formatting issues arise in the final transaction table.
π Note: The code for this project cannot be made publicly available due to academic restrictions. However, it can be shared upon request for review or discussion purposes.