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