A feature-rich, interactive C++ command-line application for creating, managing, and studying flashcards directly in your terminal. Designed for active recall, FlashTerm requires you to type answers manually to maximize memorization, and packages standard spaced repetition principles into a sleek terminal interface.
-
🧠 Spaced Repetition (Leitner System): Flashcards are sorted into 5 boxes. Answering correctly promotes a card to the next box (up to Box 5); answering incorrectly demotes it back to Box 1. You can choose to review specific boxes or prioritize weaker boxes first.
-
📅 Real Scheduling: Each box carries a review interval, so a card you know well genuinely stops appearing until it is due again. The main menu shows how many cards are due, the default review mode drills exactly those, and the most overdue cards come first.
Box Next review after 1 (weakest) 1 day 2 3 days 3 7 days 4 14 days 5 (mastered) 30 days Cards you have never reviewed are due immediately. Existing decks upgrade automatically — every card simply starts out due, keeping its box and scores.
-
🏷️ Tag System & Interactive Filtering: Tag cards (e.g.,
cpp; memory) to filter reviews, picking tags by number or name. -
✍️ Typo Tolerance: Levenshtein distance catches near misses. A minor typo prompts you to override it rather than counting it wrong.
-
✅ Multiple Accepted Answers: Separate alternatives with
|—std::unique_ptr|unique_ptr— and any of them counts. The first is shown back to you when you miss the card, the rest as also accepted. -
↩️ Undo & Fix In Place: After each answer,
utakes it back — box, scores and due date restored exactly — andeedits the card on the spot, which is when you actually notice a bad question. Editing keeps the prompt open, so you can fix a card and then undo the answer it cost you. -
🗃️ Custom Decks via CLI:
./FlashTerm vocabulary.txtloads any deck file; the default isflashcards.txt. -
📊 Deck Statistics Dashboard: Success rates, review counts, a box-by-box mastery breakdown with ASCII bars, and automatic flagging of your hardest card.
-
🛡️ Robust CSV Parser: Full double-quote support, so questions and answers can contain commas. Column layout is UTF-8 aware, so accented, CJK and emoji cards still line up.
-
💾 Crash-Safe Autosave: The deck is written after every answered card and every edit, so
Ctrl+Cmid-session costs you nothing. Saves are atomic — written to a temporary file and renamed into place — and a deck that cannot be written says so loudly instead of failing silently. -
🌀 EOF and Pipe Safety: Piped or non-interactive input auto-saves and exits cleanly rather than looping. Colour and screen clears are suppressed when output is not a terminal, or when
NO_COLORis set.
- A C++ compiler supporting C++17 (e.g.,
g++orclang++) makebuild utility
Compile the application using the provided Makefile:
makeThis creates an executable file named FlashTerm. Object files land in build/.
./FlashTerm # default deck, created on first run
./FlashTerm path/to/deck.txt # any other deckYour decks are yours: flashcards.txt is deliberately not tracked by git, so
studying never shows up as a source change.
A new deck starts empty. To fill it, choose 5. Import flashcards and give it
any file from examples/ — programming languages, tooling and human languages:
ls examples/Imported cards arrive in Box 1 and are due immediately. The examples are plain
question,answer,tags records, the shortest form of the deck format below, so
they double as a template for writing your own. Several use | to accept more
than one answer, which is worth copying: mañana really does mean both
tomorrow and morning, and git init should not be marked wrong because you
typed init.
make testCovers the text and answer-matching utilities (normalisation, Levenshtein
distance, CSV escaping, UTF-8 column widths, alternatives, undo round-trips),
the scheduling logic (calendar arithmetic, leap years, box intervals, due
dates), and the Deck persistence layer (atomic writes, write failures,
lossless import/export, legacy-deck migration, statistics).
One CSV record per card, with the last five fields optional:
question,answer,tags,correct,incorrect,box,last_reviewed,due_date
Dates are plain YYYY-MM-DD, blank when a card has never been reviewed. Answers may list alternatives separated by |. Questions and answers containing commas or quotes are quoted normally, so decks stay greppable and editable by hand.
| Menu | What it does |
|---|---|
| 1. Add flashcard | Question, answer and semicolon-separated tags. Use | for alternative answers. |
| 2. Review flashcards | Pick a mode: due cards (most overdue first), all (shuffled), by tag, difficult only (incorrect > correct), or by box. |
| 3. Manage flashcards | List, edit or delete cards. |
| 4. Display progress | Deck statistics, due counts, box distribution, hardest card, per-card rates. |
| 5. Import flashcards | Append cards from a .csv file. |
| 6. Export flashcards | Write the deck to .csv, review history included, so it re-imports without losing progress. |
| 7. List unique Tags | Every tag in the deck, sorted, with card counts. |
| 0. Save and exit | Saves and exits. (The deck is already saved after every change.) |
During a review, u undoes the last answer and e edits the current card.
| File | Responsibility |
|---|---|
src/flashcard.* |
The Flashcard model |
src/answer.* |
Accepted-answer alternatives and typo-tolerant matching |
src/date.* |
Civil-calendar arithmetic and due-date formatting |
src/schedule.* |
Box intervals, due checks, and the Leitner move for an answer |
src/text.* |
String, CSV and UTF-8 column helpers (no I/O) |
src/terminal.* |
Colour detection, screen clearing, terminal width |
src/deck.* |
The Deck class: load, atomic save, import/export, tags, statistics |
src/review.* |
Review session flow and the Leitner promotion rules |
src/ui.* |
Menus, prompts and the statistics screen |
src/main.cpp |
Argument handling and the main menu loop |
tests/tests.cpp |
Test suite (make test) |
Contributions are welcome! Please feel free to open issues or submit pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.