Terminal Expense Ledger
Build an expense ledger in C that you use from the terminal: ledger add 12.50 food "lunch" records an expense with today's date, ledger list shows them, and ledger summary prints totals per category and per month. Expenses are saved in a simple text file, one per line, so they're still there next time and can be read by other tools. Amounts are stored as whole cents to avoid rounding errors. It's a good first C project: you'll learn structs and arrays that grow with realloc, parsing text safely, reading and writing files, working with dates using time.h, command-line arguments, and building with CMake.
- Estimate
- ~8.5h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
POSIX · CMake
Project roadmap
- 01
Define the commands and file format
~1hWrite README.md: the commands (add AMOUNT CATEGORY [DESCRIPTION] [--date YYYY-MM-DD], list [--month YYYY-MM], summary [--month YYYY-MM]), the file format (one expense per line: date, amount in cents, category and description, separated by tabs), and the location of the file (an environment variable, or ledger.tsv in the current folder). Set up a CMake project with -Wall -Wextra. Done when: README.md defines the commands and file format.
- 02
Store expenses in memory
~1.5hDefine a struct Expense (date as a string YYYY-MM-DD, amount in cents as long, category and description as fixed-size char arrays) and a dynamic array that grows with realloc. Write a function that parses an amount like 12.50 into 1250 cents carefully (checking digits, at most 2 decimals, and a positive value) without using floating point. Done when: unit tests show amounts are parsed correctly and bad ones are rejected.
- 03
Load and save the file
~1.5hLoad the file with fgets and parse each line with strtok or sscanf, checking every field (a valid date, a number for the amount, and a category), and report bad lines with their line number instead of crashing. Append new expenses to the file with fopen in append mode. Done when: expenses added in one run are listed in the next, and a damaged line is reported.
- 04
Add and list expenses
~1.5hImplement add, using today's date from time and strftime unless --date is given (checked to be a real date), and validating the category (1 to 30 characters, no tabs). Implement list with aligned columns and amounts printed as 12.50, optionally filtered by month. Done when: adding and listing work with and without filters.
- 05
Print summaries
~1.5hImplement summary: totals per category, sorted by amount with qsort, with each category's share of the total, and totals per month, plus the grand total. Handle an empty ledger with a friendly message. Done when: the summary totals match the listed expenses.
- 06
Test it
~1.5hWrite a test program (with assert) for amount parsing, date checking and totals, and a shell script that runs the program with a temporary ledger file through adding, listing, summarizing and bad input, comparing the output with expected files. Run it with valgrind or AddressSanitizer. Done when: the tests pass with no memory errors.
Resources
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack