Skip to content

Commit 7c4b40d

Browse files
expense tracker functionality
1 parent bbb5f7f commit 7c4b40d

File tree

1 file changed

+246
-0
lines changed

1 file changed

+246
-0
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <time.h>
5+
6+
#define MAX_CATEGORY_LEN 50
7+
#define MAX_LINE_LEN 256
8+
#define FILENAME "expenses.csv"
9+
10+
typedef struct {
11+
char date[11];
12+
double amount;
13+
char category[MAX_CATEGORY_LEN];
14+
} Expense;
15+
16+
void clearInputBuffer() {
17+
int c;
18+
while ((c = getchar()) != '\n' && c != EOF);
19+
}
20+
21+
void getCurrentDate(char *dateStr) {
22+
time_t t = time(NULL);
23+
struct tm *tm_info = localtime(&t);
24+
strftime(dateStr, 11, "%Y-%m-%d", tm_info);
25+
}
26+
27+
void initializeFile() {
28+
FILE *file = fopen(FILENAME, "r");
29+
if (file == NULL) {
30+
file = fopen(FILENAME, "w");
31+
if (file != NULL) {
32+
fprintf(file, "Date,Amount,Category\n");
33+
fclose(file);
34+
printf("Created new expense file: %s\n\n", FILENAME);
35+
} else {
36+
printf("Error creating file!\n");
37+
}
38+
} else {
39+
fclose(file);
40+
}
41+
}
42+
43+
void addExpense() {
44+
Expense exp;
45+
FILE *file;
46+
47+
getCurrentDate(exp.date);
48+
49+
printf("\n=== Add New Expense ===\n");
50+
printf("Date: %s (today)\n", exp.date);
51+
52+
printf("Enter amount: $");
53+
if (scanf("%lf", &exp.amount) != 1 || exp.amount <= 0) {
54+
printf("Invalid amount! Please enter a positive number.\n");
55+
clearInputBuffer();
56+
return;
57+
}
58+
clearInputBuffer();
59+
60+
printf("Enter category: ");
61+
if (fgets(exp.category, MAX_CATEGORY_LEN, stdin) == NULL) {
62+
printf("Error reading category!\n");
63+
return;
64+
}
65+
exp.category[strcspn(exp.category, "\n")] = 0;
66+
67+
if (strlen(exp.category) == 0) {
68+
printf("Category cannot be empty!\n");
69+
return;
70+
}
71+
72+
file = fopen(FILENAME, "a");
73+
if (file == NULL) {
74+
printf("Error opening file!\n");
75+
return;
76+
}
77+
78+
fprintf(file, "%s,%.2f,%s\n", exp.date, exp.amount, exp.category);
79+
fclose(file);
80+
81+
printf("\n✓ Expense added successfully!\n");
82+
printf(" Date: %s\n", exp.date);
83+
printf(" Amount: $%.2f\n", exp.amount);
84+
printf(" Category: %s\n", exp.category);
85+
}
86+
87+
void viewExpenses() {
88+
FILE *file;
89+
char line[MAX_LINE_LEN];
90+
int count = 0;
91+
double total = 0.0;
92+
93+
file = fopen(FILENAME, "r");
94+
if (file == NULL) {
95+
printf("No expenses found! File doesn't exist.\n");
96+
return;
97+
}
98+
99+
printf("\n=== All Expenses ===\n");
100+
printf("%-12s %-12s %-20s\n", "Date", "Amount", "Category");
101+
printf("------------------------------------------------\n");
102+
103+
fgets(line, MAX_LINE_LEN, file);
104+
105+
while (fgets(line, MAX_LINE_LEN, file) != NULL) {
106+
char date[11];
107+
double amount;
108+
char category[MAX_CATEGORY_LEN];
109+
110+
char *token = strtok(line, ",");
111+
if (token != NULL) strcpy(date, token);
112+
113+
token = strtok(NULL, ",");
114+
if (token != NULL) amount = atof(token);
115+
116+
token = strtok(NULL, "\n");
117+
if (token != NULL) strcpy(category, token);
118+
119+
printf("%-12s $%-11.2f %-20s\n", date, amount, category);
120+
total += amount;
121+
count++;
122+
}
123+
124+
fclose(file);
125+
126+
printf("------------------------------------------------\n");
127+
printf("Total Expenses: %d\n", count);
128+
printf("Total Amount: $%.2f\n", total);
129+
}
130+
131+
void viewSummaryByCategory() {
132+
FILE *file;
133+
char line[MAX_LINE_LEN];
134+
135+
typedef struct {
136+
char category[MAX_CATEGORY_LEN];
137+
double total;
138+
int count;
139+
} CategorySummary;
140+
141+
CategorySummary summaries[100];
142+
int numCategories = 0;
143+
144+
file = fopen(FILENAME, "r");
145+
if (file == NULL) {
146+
printf("No expenses found!\n");
147+
return;
148+
}
149+
150+
fgets(line, MAX_LINE_LEN, file);
151+
152+
while (fgets(line, MAX_LINE_LEN, file) != NULL) {
153+
char category[MAX_CATEGORY_LEN];
154+
double amount;
155+
156+
strtok(line, ",");
157+
char *token = strtok(NULL, ",");
158+
if (token != NULL) amount = atof(token);
159+
160+
token = strtok(NULL, "\n");
161+
if (token != NULL) strcpy(category, token);
162+
163+
int found = 0;
164+
for (int i = 0; i < numCategories; i++) {
165+
if (strcmp(summaries[i].category, category) == 0) {
166+
summaries[i].total += amount;
167+
summaries[i].count++;
168+
found = 1;
169+
break;
170+
}
171+
}
172+
173+
if (!found && numCategories < 100) {
174+
strcpy(summaries[numCategories].category, category);
175+
summaries[numCategories].total = amount;
176+
summaries[numCategories].count = 1;
177+
numCategories++;
178+
}
179+
}
180+
181+
fclose(file);
182+
183+
printf("\n=== Expense Summary by Category ===\n");
184+
printf("%-20s %-12s %-10s\n", "Category", "Total", "Count");
185+
printf("------------------------------------------------\n");
186+
187+
for (int i = 0; i < numCategories; i++) {
188+
printf("%-20s $%-11.2f %d\n",
189+
summaries[i].category,
190+
summaries[i].total,
191+
summaries[i].count);
192+
}
193+
}
194+
195+
void displayMenu() {
196+
printf("\n╔════════════════════════════════════╗\n");
197+
printf("║ EXPENSE TRACKER MENU ║\n");
198+
printf("╠════════════════════════════════════╣\n");
199+
printf("║ 1. Add Expense ║\n");
200+
printf("║ 2. View All Expenses ║\n");
201+
printf("║ 3. View Summary by Category ║\n");
202+
printf("║ 4. Exit ║\n");
203+
printf("╚════════════════════════════════════╝\n");
204+
printf("Choose an option: ");
205+
}
206+
207+
int main() {
208+
int choice;
209+
210+
printf("╔════════════════════════════════════╗\n");
211+
printf("║ WELCOME TO EXPENSE TRACKER ║\n");
212+
printf("╚════════════════════════════════════╝\n\n");
213+
214+
initializeFile();
215+
216+
while (1) {
217+
displayMenu();
218+
219+
if (scanf("%d", &choice) != 1) {
220+
printf("Invalid input! Please enter a number.\n");
221+
clearInputBuffer();
222+
continue;
223+
}
224+
clearInputBuffer();
225+
226+
switch (choice) {
227+
case 1:
228+
addExpense();
229+
break;
230+
case 2:
231+
viewExpenses();
232+
break;
233+
case 3:
234+
viewSummaryByCategory();
235+
break;
236+
case 4:
237+
printf("\nThank you for using Expense Tracker!\n");
238+
printf("Your expenses are saved in '%s'\n", FILENAME);
239+
return 0;
240+
default:
241+
printf("Invalid choice! Please select 1-4.\n");
242+
}
243+
}
244+
245+
return 0;
246+
}

0 commit comments

Comments
 (0)