From bbb5f7f50c1f9fd973bf2e188b0a292cce21e5d0 Mon Sep 17 00:00:00 2001 From: riddhima-7321 <132067601+riddhima-7321@users.noreply.github.com> Date: Tue, 28 Oct 2025 18:56:59 +0530 Subject: [PATCH 1/4] Add files via upload Expense Tracker in C. Saves data in expenses.csv for easy viewing in spreadsheet apps --- C/Expense_tracker.c | 246 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 C/Expense_tracker.c diff --git a/C/Expense_tracker.c b/C/Expense_tracker.c new file mode 100644 index 0000000..ae8d0cc --- /dev/null +++ b/C/Expense_tracker.c @@ -0,0 +1,246 @@ +#include +#include +#include +#include + +#define MAX_CATEGORY_LEN 50 +#define MAX_LINE_LEN 256 +#define FILENAME "expenses.csv" + +typedef struct { + char date[11]; + double amount; + char category[MAX_CATEGORY_LEN]; +} Expense; + +void clearInputBuffer() { + int c; + while ((c = getchar()) != '\n' && c != EOF); +} + +void getCurrentDate(char *dateStr) { + time_t t = time(NULL); + struct tm *tm_info = localtime(&t); + strftime(dateStr, 11, "%Y-%m-%d", tm_info); +} + +void initializeFile() { + FILE *file = fopen(FILENAME, "r"); + if (file == NULL) { + file = fopen(FILENAME, "w"); + if (file != NULL) { + fprintf(file, "Date,Amount,Category\n"); + fclose(file); + printf("Created new expense file: %s\n\n", FILENAME); + } else { + printf("Error creating file!\n"); + } + } else { + fclose(file); + } +} + +void addExpense() { + Expense exp; + FILE *file; + + getCurrentDate(exp.date); + + printf("\n=== Add New Expense ===\n"); + printf("Date: %s (today)\n", exp.date); + + printf("Enter amount: $"); + if (scanf("%lf", &exp.amount) != 1 || exp.amount <= 0) { + printf("Invalid amount! Please enter a positive number.\n"); + clearInputBuffer(); + return; + } + clearInputBuffer(); + + printf("Enter category: "); + if (fgets(exp.category, MAX_CATEGORY_LEN, stdin) == NULL) { + printf("Error reading category!\n"); + return; + } + exp.category[strcspn(exp.category, "\n")] = 0; + + if (strlen(exp.category) == 0) { + printf("Category cannot be empty!\n"); + return; + } + + file = fopen(FILENAME, "a"); + if (file == NULL) { + printf("Error opening file!\n"); + return; + } + + fprintf(file, "%s,%.2f,%s\n", exp.date, exp.amount, exp.category); + fclose(file); + + printf("\n✓ Expense added successfully!\n"); + printf(" Date: %s\n", exp.date); + printf(" Amount: $%.2f\n", exp.amount); + printf(" Category: %s\n", exp.category); +} + +void viewExpenses() { + FILE *file; + char line[MAX_LINE_LEN]; + int count = 0; + double total = 0.0; + + file = fopen(FILENAME, "r"); + if (file == NULL) { + printf("No expenses found! File doesn't exist.\n"); + return; + } + + printf("\n=== All Expenses ===\n"); + printf("%-12s %-12s %-20s\n", "Date", "Amount", "Category"); + printf("------------------------------------------------\n"); + + fgets(line, MAX_LINE_LEN, file); + + while (fgets(line, MAX_LINE_LEN, file) != NULL) { + char date[11]; + double amount; + char category[MAX_CATEGORY_LEN]; + + char *token = strtok(line, ","); + if (token != NULL) strcpy(date, token); + + token = strtok(NULL, ","); + if (token != NULL) amount = atof(token); + + token = strtok(NULL, "\n"); + if (token != NULL) strcpy(category, token); + + printf("%-12s $%-11.2f %-20s\n", date, amount, category); + total += amount; + count++; + } + + fclose(file); + + printf("------------------------------------------------\n"); + printf("Total Expenses: %d\n", count); + printf("Total Amount: $%.2f\n", total); +} + +void viewSummaryByCategory() { + FILE *file; + char line[MAX_LINE_LEN]; + + typedef struct { + char category[MAX_CATEGORY_LEN]; + double total; + int count; + } CategorySummary; + + CategorySummary summaries[100]; + int numCategories = 0; + + file = fopen(FILENAME, "r"); + if (file == NULL) { + printf("No expenses found!\n"); + return; + } + + fgets(line, MAX_LINE_LEN, file); + + while (fgets(line, MAX_LINE_LEN, file) != NULL) { + char category[MAX_CATEGORY_LEN]; + double amount; + + strtok(line, ","); + char *token = strtok(NULL, ","); + if (token != NULL) amount = atof(token); + + token = strtok(NULL, "\n"); + if (token != NULL) strcpy(category, token); + + int found = 0; + for (int i = 0; i < numCategories; i++) { + if (strcmp(summaries[i].category, category) == 0) { + summaries[i].total += amount; + summaries[i].count++; + found = 1; + break; + } + } + + if (!found && numCategories < 100) { + strcpy(summaries[numCategories].category, category); + summaries[numCategories].total = amount; + summaries[numCategories].count = 1; + numCategories++; + } + } + + fclose(file); + + printf("\n=== Expense Summary by Category ===\n"); + printf("%-20s %-12s %-10s\n", "Category", "Total", "Count"); + printf("------------------------------------------------\n"); + + for (int i = 0; i < numCategories; i++) { + printf("%-20s $%-11.2f %d\n", + summaries[i].category, + summaries[i].total, + summaries[i].count); + } +} + +void displayMenu() { + printf("\n╔════════════════════════════════════╗\n"); + printf("║ EXPENSE TRACKER MENU ║\n"); + printf("╠════════════════════════════════════╣\n"); + printf("║ 1. Add Expense ║\n"); + printf("║ 2. View All Expenses ║\n"); + printf("║ 3. View Summary by Category ║\n"); + printf("║ 4. Exit ║\n"); + printf("╚════════════════════════════════════╝\n"); + printf("Choose an option: "); +} + +int main() { + int choice; + + printf("╔════════════════════════════════════╗\n"); + printf("║ WELCOME TO EXPENSE TRACKER ║\n"); + printf("╚════════════════════════════════════╝\n\n"); + + initializeFile(); + + while (1) { + displayMenu(); + + if (scanf("%d", &choice) != 1) { + printf("Invalid input! Please enter a number.\n"); + clearInputBuffer(); + continue; + } + clearInputBuffer(); + + switch (choice) { + case 1: + addExpense(); + break; + case 2: + viewExpenses(); + break; + case 3: + viewSummaryByCategory(); + break; + case 4: + printf("\nThank you for using Expense Tracker!\n"); + printf("Your expenses are saved in '%s'\n", FILENAME); + return 0; + default: + printf("Invalid choice! Please select 1-4.\n"); + } + } + + return 0; +} \ No newline at end of file From 7c4b40de5dceaf601b914ac041cfea21095ee3b4 Mon Sep 17 00:00:00 2001 From: riddhima-7321 <132067601+riddhima-7321@users.noreply.github.com> Date: Fri, 31 Oct 2025 09:51:42 +0530 Subject: [PATCH 2/4] expense tracker functionality --- C/Expense_Tracker/Expense-tracker.c | 246 ++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 C/Expense_Tracker/Expense-tracker.c diff --git a/C/Expense_Tracker/Expense-tracker.c b/C/Expense_Tracker/Expense-tracker.c new file mode 100644 index 0000000..85dc86b --- /dev/null +++ b/C/Expense_Tracker/Expense-tracker.c @@ -0,0 +1,246 @@ +#include +#include +#include +#include + +#define MAX_CATEGORY_LEN 50 +#define MAX_LINE_LEN 256 +#define FILENAME "expenses.csv" + +typedef struct { + char date[11]; + double amount; + char category[MAX_CATEGORY_LEN]; +} Expense; + +void clearInputBuffer() { + int c; + while ((c = getchar()) != '\n' && c != EOF); +} + +void getCurrentDate(char *dateStr) { + time_t t = time(NULL); + struct tm *tm_info = localtime(&t); + strftime(dateStr, 11, "%Y-%m-%d", tm_info); +} + +void initializeFile() { + FILE *file = fopen(FILENAME, "r"); + if (file == NULL) { + file = fopen(FILENAME, "w"); + if (file != NULL) { + fprintf(file, "Date,Amount,Category\n"); + fclose(file); + printf("Created new expense file: %s\n\n", FILENAME); + } else { + printf("Error creating file!\n"); + } + } else { + fclose(file); + } +} + +void addExpense() { + Expense exp; + FILE *file; + + getCurrentDate(exp.date); + + printf("\n=== Add New Expense ===\n"); + printf("Date: %s (today)\n", exp.date); + + printf("Enter amount: $"); + if (scanf("%lf", &exp.amount) != 1 || exp.amount <= 0) { + printf("Invalid amount! Please enter a positive number.\n"); + clearInputBuffer(); + return; + } + clearInputBuffer(); + + printf("Enter category: "); + if (fgets(exp.category, MAX_CATEGORY_LEN, stdin) == NULL) { + printf("Error reading category!\n"); + return; + } + exp.category[strcspn(exp.category, "\n")] = 0; + + if (strlen(exp.category) == 0) { + printf("Category cannot be empty!\n"); + return; + } + + file = fopen(FILENAME, "a"); + if (file == NULL) { + printf("Error opening file!\n"); + return; + } + + fprintf(file, "%s,%.2f,%s\n", exp.date, exp.amount, exp.category); + fclose(file); + + printf("\n✓ Expense added successfully!\n"); + printf(" Date: %s\n", exp.date); + printf(" Amount: $%.2f\n", exp.amount); + printf(" Category: %s\n", exp.category); +} + +void viewExpenses() { + FILE *file; + char line[MAX_LINE_LEN]; + int count = 0; + double total = 0.0; + + file = fopen(FILENAME, "r"); + if (file == NULL) { + printf("No expenses found! File doesn't exist.\n"); + return; + } + + printf("\n=== All Expenses ===\n"); + printf("%-12s %-12s %-20s\n", "Date", "Amount", "Category"); + printf("------------------------------------------------\n"); + + fgets(line, MAX_LINE_LEN, file); + + while (fgets(line, MAX_LINE_LEN, file) != NULL) { + char date[11]; + double amount; + char category[MAX_CATEGORY_LEN]; + + char *token = strtok(line, ","); + if (token != NULL) strcpy(date, token); + + token = strtok(NULL, ","); + if (token != NULL) amount = atof(token); + + token = strtok(NULL, "\n"); + if (token != NULL) strcpy(category, token); + + printf("%-12s $%-11.2f %-20s\n", date, amount, category); + total += amount; + count++; + } + + fclose(file); + + printf("------------------------------------------------\n"); + printf("Total Expenses: %d\n", count); + printf("Total Amount: $%.2f\n", total); +} + +void viewSummaryByCategory() { + FILE *file; + char line[MAX_LINE_LEN]; + + typedef struct { + char category[MAX_CATEGORY_LEN]; + double total; + int count; + } CategorySummary; + + CategorySummary summaries[100]; + int numCategories = 0; + + file = fopen(FILENAME, "r"); + if (file == NULL) { + printf("No expenses found!\n"); + return; + } + + fgets(line, MAX_LINE_LEN, file); + + while (fgets(line, MAX_LINE_LEN, file) != NULL) { + char category[MAX_CATEGORY_LEN]; + double amount; + + strtok(line, ","); + char *token = strtok(NULL, ","); + if (token != NULL) amount = atof(token); + + token = strtok(NULL, "\n"); + if (token != NULL) strcpy(category, token); + + int found = 0; + for (int i = 0; i < numCategories; i++) { + if (strcmp(summaries[i].category, category) == 0) { + summaries[i].total += amount; + summaries[i].count++; + found = 1; + break; + } + } + + if (!found && numCategories < 100) { + strcpy(summaries[numCategories].category, category); + summaries[numCategories].total = amount; + summaries[numCategories].count = 1; + numCategories++; + } + } + + fclose(file); + + printf("\n=== Expense Summary by Category ===\n"); + printf("%-20s %-12s %-10s\n", "Category", "Total", "Count"); + printf("------------------------------------------------\n"); + + for (int i = 0; i < numCategories; i++) { + printf("%-20s $%-11.2f %d\n", + summaries[i].category, + summaries[i].total, + summaries[i].count); + } +} + +void displayMenu() { + printf("\n╔════════════════════════════════════╗\n"); + printf("║ EXPENSE TRACKER MENU ║\n"); + printf("╠════════════════════════════════════╣\n"); + printf("║ 1. Add Expense ║\n"); + printf("║ 2. View All Expenses ║\n"); + printf("║ 3. View Summary by Category ║\n"); + printf("║ 4. Exit ║\n"); + printf("╚════════════════════════════════════╝\n"); + printf("Choose an option: "); +} + +int main() { + int choice; + + printf("╔════════════════════════════════════╗\n"); + printf("║ WELCOME TO EXPENSE TRACKER ║\n"); + printf("╚════════════════════════════════════╝\n\n"); + + initializeFile(); + + while (1) { + displayMenu(); + + if (scanf("%d", &choice) != 1) { + printf("Invalid input! Please enter a number.\n"); + clearInputBuffer(); + continue; + } + clearInputBuffer(); + + switch (choice) { + case 1: + addExpense(); + break; + case 2: + viewExpenses(); + break; + case 3: + viewSummaryByCategory(); + break; + case 4: + printf("\nThank you for using Expense Tracker!\n"); + printf("Your expenses are saved in '%s'\n", FILENAME); + return 0; + default: + printf("Invalid choice! Please select 1-4.\n"); + } + } + + return 0; +} From 2ad4bd76d71ff9405055f4edafd3384f43adbe37 Mon Sep 17 00:00:00 2001 From: riddhima-7321 <132067601+riddhima-7321@users.noreply.github.com> Date: Fri, 31 Oct 2025 10:10:48 +0530 Subject: [PATCH 3/4] Add README for Expense Tracker This README provides an overview of the Expense Tracker program, including features, usage instructions, and future enhancement ideas. --- C/Expense_Tracker/Readme.md | 125 ++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 C/Expense_Tracker/Readme.md diff --git a/C/Expense_Tracker/Readme.md b/C/Expense_Tracker/Readme.md new file mode 100644 index 0000000..c845746 --- /dev/null +++ b/C/Expense_Tracker/Readme.md @@ -0,0 +1,125 @@ +Expense Tracker (C Program) + +A simple and lightweight command-line Expense Tracker written in C. +It allows you to record, view, and summarize expenses by category — all stored in a CSV file for easy access. + +Features + +Automatically records the current date +Add new expenses with amount and category +Stores data in a expenses.csv file +View all recorded expenses in a tabular format + +Summary of expenses grouped by category + +Persistent data across sessions (CSV-based) + +File Structure +. +├─ expense_tracker.c # Source code +└─ readme.md + +How to Compile & Run + +Make sure you have a C compiler installed (like GCC). + +Compile: +gcc expense_tracker.c -o expense_tracker + +Run: +./expense_tracker + +CSV Format + +The program automatically generates expenses.csv (if not present) with the following header: + +Date,Amount,Category +2025-10-30,199.99,Groceries +2025-10-31,550.00,Travel +... + + +This means you can open it directly in Excel, Google Sheets, or any data analytics tool. + +Menu Options + +When you run the program, you'll see: + +1. Add Expense +2. View All Expenses +3. View Summary by Category +4. Exit + +Add Expense + +Enter amount + +Enter category + +Date auto-fills to today + +Example: + +Enter amount: $250 +Enter category: Utilities +Expense added successfully! +View All Expenses + +Displays all recorded entries: + +Date Amount Category +2025-10-30 $250.00 Utilities + + +Additionally shows: + +Total expense count + +Overall amount spent + +Summary by Category + +Groups expenses by category: + +Category Total Count +Groceries $500.00 3 +Travel $550.00 1 + +Persistent Storage + +All expenses are permanently saved inside expenses.csv, so nothing is lost when the program closes. + +Concepts Used + +File handling (fopen, fprintf, fgets) + +String tokenization (strtok) + +Structs for data modeling + +Looping, conditions, and input validation + +Basic memory-safe input cleanup +Input Validation + +The program prevents: + +Negative/zero amounts +Empty categories +Invalid main menu input + +Future Enhancements (Ideas) + +Delete/Update expenses + +Filter by date range + +Export monthly/annual summaries + +Category-wise budgeting + +Graphical visualization using Python integration + +Author + +Developed as a simple terminal-based expense management utility written in C. From 413b39ec59cdf54b6be6003ee5e4e6689e78f011 Mon Sep 17 00:00:00 2001 From: devmalik7 Date: Fri, 31 Oct 2025 12:13:43 +0530 Subject: [PATCH 4/4] Delete C/Expense_tracker.c --- C/Expense_tracker.c | 246 -------------------------------------------- 1 file changed, 246 deletions(-) delete mode 100644 C/Expense_tracker.c diff --git a/C/Expense_tracker.c b/C/Expense_tracker.c deleted file mode 100644 index ae8d0cc..0000000 --- a/C/Expense_tracker.c +++ /dev/null @@ -1,246 +0,0 @@ -#include -#include -#include -#include - -#define MAX_CATEGORY_LEN 50 -#define MAX_LINE_LEN 256 -#define FILENAME "expenses.csv" - -typedef struct { - char date[11]; - double amount; - char category[MAX_CATEGORY_LEN]; -} Expense; - -void clearInputBuffer() { - int c; - while ((c = getchar()) != '\n' && c != EOF); -} - -void getCurrentDate(char *dateStr) { - time_t t = time(NULL); - struct tm *tm_info = localtime(&t); - strftime(dateStr, 11, "%Y-%m-%d", tm_info); -} - -void initializeFile() { - FILE *file = fopen(FILENAME, "r"); - if (file == NULL) { - file = fopen(FILENAME, "w"); - if (file != NULL) { - fprintf(file, "Date,Amount,Category\n"); - fclose(file); - printf("Created new expense file: %s\n\n", FILENAME); - } else { - printf("Error creating file!\n"); - } - } else { - fclose(file); - } -} - -void addExpense() { - Expense exp; - FILE *file; - - getCurrentDate(exp.date); - - printf("\n=== Add New Expense ===\n"); - printf("Date: %s (today)\n", exp.date); - - printf("Enter amount: $"); - if (scanf("%lf", &exp.amount) != 1 || exp.amount <= 0) { - printf("Invalid amount! Please enter a positive number.\n"); - clearInputBuffer(); - return; - } - clearInputBuffer(); - - printf("Enter category: "); - if (fgets(exp.category, MAX_CATEGORY_LEN, stdin) == NULL) { - printf("Error reading category!\n"); - return; - } - exp.category[strcspn(exp.category, "\n")] = 0; - - if (strlen(exp.category) == 0) { - printf("Category cannot be empty!\n"); - return; - } - - file = fopen(FILENAME, "a"); - if (file == NULL) { - printf("Error opening file!\n"); - return; - } - - fprintf(file, "%s,%.2f,%s\n", exp.date, exp.amount, exp.category); - fclose(file); - - printf("\n✓ Expense added successfully!\n"); - printf(" Date: %s\n", exp.date); - printf(" Amount: $%.2f\n", exp.amount); - printf(" Category: %s\n", exp.category); -} - -void viewExpenses() { - FILE *file; - char line[MAX_LINE_LEN]; - int count = 0; - double total = 0.0; - - file = fopen(FILENAME, "r"); - if (file == NULL) { - printf("No expenses found! File doesn't exist.\n"); - return; - } - - printf("\n=== All Expenses ===\n"); - printf("%-12s %-12s %-20s\n", "Date", "Amount", "Category"); - printf("------------------------------------------------\n"); - - fgets(line, MAX_LINE_LEN, file); - - while (fgets(line, MAX_LINE_LEN, file) != NULL) { - char date[11]; - double amount; - char category[MAX_CATEGORY_LEN]; - - char *token = strtok(line, ","); - if (token != NULL) strcpy(date, token); - - token = strtok(NULL, ","); - if (token != NULL) amount = atof(token); - - token = strtok(NULL, "\n"); - if (token != NULL) strcpy(category, token); - - printf("%-12s $%-11.2f %-20s\n", date, amount, category); - total += amount; - count++; - } - - fclose(file); - - printf("------------------------------------------------\n"); - printf("Total Expenses: %d\n", count); - printf("Total Amount: $%.2f\n", total); -} - -void viewSummaryByCategory() { - FILE *file; - char line[MAX_LINE_LEN]; - - typedef struct { - char category[MAX_CATEGORY_LEN]; - double total; - int count; - } CategorySummary; - - CategorySummary summaries[100]; - int numCategories = 0; - - file = fopen(FILENAME, "r"); - if (file == NULL) { - printf("No expenses found!\n"); - return; - } - - fgets(line, MAX_LINE_LEN, file); - - while (fgets(line, MAX_LINE_LEN, file) != NULL) { - char category[MAX_CATEGORY_LEN]; - double amount; - - strtok(line, ","); - char *token = strtok(NULL, ","); - if (token != NULL) amount = atof(token); - - token = strtok(NULL, "\n"); - if (token != NULL) strcpy(category, token); - - int found = 0; - for (int i = 0; i < numCategories; i++) { - if (strcmp(summaries[i].category, category) == 0) { - summaries[i].total += amount; - summaries[i].count++; - found = 1; - break; - } - } - - if (!found && numCategories < 100) { - strcpy(summaries[numCategories].category, category); - summaries[numCategories].total = amount; - summaries[numCategories].count = 1; - numCategories++; - } - } - - fclose(file); - - printf("\n=== Expense Summary by Category ===\n"); - printf("%-20s %-12s %-10s\n", "Category", "Total", "Count"); - printf("------------------------------------------------\n"); - - for (int i = 0; i < numCategories; i++) { - printf("%-20s $%-11.2f %d\n", - summaries[i].category, - summaries[i].total, - summaries[i].count); - } -} - -void displayMenu() { - printf("\n╔════════════════════════════════════╗\n"); - printf("║ EXPENSE TRACKER MENU ║\n"); - printf("╠════════════════════════════════════╣\n"); - printf("║ 1. Add Expense ║\n"); - printf("║ 2. View All Expenses ║\n"); - printf("║ 3. View Summary by Category ║\n"); - printf("║ 4. Exit ║\n"); - printf("╚════════════════════════════════════╝\n"); - printf("Choose an option: "); -} - -int main() { - int choice; - - printf("╔════════════════════════════════════╗\n"); - printf("║ WELCOME TO EXPENSE TRACKER ║\n"); - printf("╚════════════════════════════════════╝\n\n"); - - initializeFile(); - - while (1) { - displayMenu(); - - if (scanf("%d", &choice) != 1) { - printf("Invalid input! Please enter a number.\n"); - clearInputBuffer(); - continue; - } - clearInputBuffer(); - - switch (choice) { - case 1: - addExpense(); - break; - case 2: - viewExpenses(); - break; - case 3: - viewSummaryByCategory(); - break; - case 4: - printf("\nThank you for using Expense Tracker!\n"); - printf("Your expenses are saved in '%s'\n", FILENAME); - return 0; - default: - printf("Invalid choice! Please select 1-4.\n"); - } - } - - return 0; -} \ No newline at end of file