fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdbool.h>
  5. #include <curl/curl.h>
  6.  
  7. #define BASE_CURRENCY "USD"
  8.  
  9. // Define the allowed expense categories
  10. const char *allowedCategories[] = {
  11. "Housing", "Transportation", "Food", "Healthcare", "Utilities", "Debt",
  12. "Personal Care", "Entertainment", "Insurance", "Education", "Savings/Investments",
  13. "Clothing", "Charity", "Travel", "Miscellaneous"
  14. };
  15.  
  16. // Function prototypes
  17. void addExpense(FILE *file);
  18. void displayExpensesAndTotal(FILE *file);
  19. void displayExpensesPerMonthAndTotal(FILE *file);
  20. void editExpense(FILE *file, const char *filename);
  21. void deleteExpense(FILE *file, const char *filename);
  22. void displayCategories();
  23. void categorizeSpending(FILE *file);
  24. void trackBudget(FILE *file);
  25. size_t write_callback(char *ptr, size_t size, size_t nmemb, char *data);
  26. double getExchangeRate(const char *from, const char *to);
  27.  
  28. int main() {
  29. char first_name[50], last_name[50];
  30. printf("Enter your first and last name: ");
  31. scanf("%s %s", first_name, last_name);
  32.  
  33. // Create a file with the user's name to store expenses or open existing file if it exists
  34. char filename[150]; // Assuming a maximum length of 150 characters for the filename
  35. sprintf(filename, "%s_%s_expenses.txt", first_name, last_name);
  36.  
  37. int choice;
  38.  
  39. do {
  40. printf("\nCurrent User: %s %s\n", first_name, last_name);
  41. printf("Expense Tracker Menu\n");
  42. printf("1. Add Expense\n");
  43. printf("2. Display Expenses and Total\n");
  44. printf("3. Display Expenses per Month and Total\n");
  45. printf("4. Edit Expense\n");
  46. printf("5. Delete Expense\n");
  47. printf("6. Categorize Spending\n");
  48. printf("7. Track Budget\n");
  49. printf("8. Exit\n");
  50. printf("Enter your choice: ");
  51. scanf("%d", &choice);
  52.  
  53. FILE *file = fopen(filename, "a+");
  54. if (file == NULL) {
  55. printf("Error opening file!\n");
  56. return 1;
  57. }
  58.  
  59. switch (choice) {
  60. case 1:
  61. addExpense(file);
  62. break;
  63. case 2:
  64. displayExpensesAndTotal(file);
  65. break;
  66. case 3:
  67. displayExpensesPerMonthAndTotal(file);
  68. break;
  69. case 4:
  70. editExpense(file, filename);
  71. break;
  72. case 5:
  73. deleteExpense(file, filename);
  74. break;
  75. case 6:
  76. categorizeSpending(file);
  77. break;
  78. case 7:
  79. trackBudget(file);
  80. break;
  81. case 8:
  82. printf("Exiting...\n");
  83. fclose(file); // Close the file before exiting
  84. break;
  85. default:
  86. printf("Invalid choice! Please try again.\n");
  87. }
  88. } while (choice != 8);
  89.  
  90. return 0;
  91. }
  92.  
  93. void addExpense(FILE *file) {
  94. printf("Available Expense Categories:\n");
  95. displayCategories();
  96.  
  97. char category[50];
  98. float amount;
  99. char date[20];
  100. char currency[4]; // Assuming currency code is 3 characters long
  101.  
  102. int categoryNum;
  103. // Input validation for category number
  104. while (true) {
  105. printf("Enter category number: ");
  106. if (scanf("%d", &categoryNum) != 1 || categoryNum < 1 || categoryNum > sizeof(allowedCategories) / sizeof(allowedCategories[0])) {
  107. printf("Invalid category number! Please choose a valid category number.\n");
  108. // Clear input buffer
  109. while (getchar() != '\n');
  110. } else {
  111. strcpy(category, allowedCategories[categoryNum - 1]);
  112. break;
  113. }
  114. }
  115.  
  116. // Input validation for amount
  117. while (true) {
  118. printf("Enter amount: ");
  119. if (scanf("%f", &amount) == 1 && amount > 0.0f)
  120. break;
  121. else {
  122. printf("Invalid input! Please enter a valid amount greater than 0.\n");
  123. // Clear input buffer
  124. while (getchar() != '\n');
  125. }
  126. }
  127.  
  128. // Input validation for date format (DD-MM-YYYY)
  129. char dateInput[11]; // Assuming maximum length of the date input is 10 characters (including null terminator)
  130. while (true) {
  131. printf("Enter date (DD-MM-YYYY): ");
  132. if (scanf("%10s", dateInput) != 1) {
  133. printf("Invalid input! Please enter the date in DD-MM-YYYY format.\n");
  134. // Clear input buffer
  135. while (getchar() != '\n');
  136. continue;
  137. }
  138.  
  139. // Parse date input into day, month, and year components
  140. int day, month, year;
  141. if (sscanf(dateInput, "%d-%d-%d", &day, &month, &year) != 3) {
  142. printf("Invalid date format! Please enter the date in DD-MM-YYYY format.\n");
  143. continue;
  144. }
  145.  
  146. // Validate day, month, and year ranges
  147. if (day < 1 || day > 31 || month < 1 || month > 12 || year < 1900 || year > 9999) {
  148. printf("Invalid date! Please enter a valid date.\n");
  149. continue;
  150. }
  151.  
  152. // Date input is valid
  153. sprintf(date, "%02d-%02d-%04d", day, month, year);
  154. break;
  155. }
  156.  
  157. // Input currency code
  158. printf("Enter currency code (e.g., USD, EUR): ");
  159. scanf("%s", currency);
  160.  
  161. // Convert currency to base currency (USD)
  162. double exchangeRate = getExchangeRate(currency, BASE_CURRENCY);
  163. if (exchangeRate < 0) {
  164. fprintf(stderr, "Failed to get exchange rate for %s to %s\n", currency, BASE_CURRENCY);
  165. return;
  166. }
  167.  
  168. // Convert amount to base currency
  169. amount *= exchangeRate;
  170.  
  171. // Save expense to file
  172. fprintf(file, "%s %.2f %s %s\n", category, amount, BASE_CURRENCY, date);
  173. printf("Expense added successfully!\n");
  174. }
  175.  
  176. void displayExpensesAndTotal(FILE *file) {
  177. rewind(file); // Move file pointer to the beginning
  178. char category[50];
  179. float amount;
  180. char currency[4];
  181. char date[20];
  182. float total = 0.0f;
  183. int expenseCount = 0;
  184.  
  185. // Check if there are any expenses in the file
  186. if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
  187. printf("No expenses recorded.\n");
  188. return;
  189. }
  190.  
  191. printf("Index Category Amount Currency Date\n");
  192. do {
  193. printf("%d\t%-15s%.2f\t%-3s\t%s\n", ++expenseCount, category, amount, currency, date);
  194. total += amount;
  195. } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);
  196.  
  197. printf("\nTotal Expenses: $%.2f\n", total);
  198. }
  199.  
  200. void displayExpensesPerMonthAndTotal(FILE *file) {
  201. rewind(file); // Move file pointer to the beginning
  202. char category[50];
  203. float amount;
  204. char currency[4];
  205. char date[20];
  206. float total = 0.0f;
  207.  
  208. // Buffer to store month and year in MM-YYYY format
  209. char inputMonthYear[8];
  210.  
  211. printf("Enter month and year (MM-YYYY): ");
  212. scanf("%s", inputMonthYear);
  213.  
  214. bool foundExpenses = false;
  215.  
  216. while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4) {
  217. // Extract month and year from the date
  218. char expenseMonthYear[8];
  219. strncpy(expenseMonthYear, date + 3, 7); // Extract MM-YYYY from DD-MM-YYYY
  220. expenseMonthYear[7] = '\0';
  221.  
  222. // Check if the extracted month and year match the user-provided input
  223. if (strcmp(expenseMonthYear, inputMonthYear) == 0) {
  224. if (!foundExpenses) {
  225. printf("Category\tAmount\tCurrency\tDate\n");
  226. foundExpenses = true;
  227. }
  228. printf("%-15s%.2f\t%-3s\t%s\n", category, amount, currency, date);
  229. total += amount;
  230. }
  231. }
  232.  
  233. if (!foundExpenses) {
  234. printf("No expenses for %s\n", inputMonthYear);
  235. return;
  236. }
  237.  
  238. printf("\nTotal Expenses for %s: $%.2f\n", inputMonthYear, total);
  239. }
  240.  
  241. void editExpense(FILE *file, const char *filename) {
  242. // Display current expenses
  243. printf("Current Expenses:\n");
  244.  
  245. // Move file pointer to the beginning
  246.  
  247. char category[50];
  248. float amount;
  249. char currency[4];
  250. char date[20];
  251. int currentIndex = 1;
  252. bool found = false;
  253.  
  254. // Check if there are any expenses in the file
  255. if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
  256. printf("No expenses recorded.\n");
  257. return;
  258. }
  259.  
  260. printf("Index Category Amount Currency Date\n");
  261. do {
  262. printf("%d\t%-15s%.2f\t%-3s\t%s\n", currentIndex, category, amount, currency, date);
  263. currentIndex++;
  264. } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);
  265.  
  266. int index;
  267. printf("Enter the index of the expense you want to edit: ");
  268. scanf("%d", &index);
  269.  
  270. // Move file pointer to the beginning
  271.  
  272. // Create a temporary file to store updated data
  273. char tempFilename[150];
  274. sprintf(tempFilename, "temp_%s", filename);
  275. FILE *tempFile = fopen(tempFilename, "w+");
  276. if (tempFile == NULL) {
  277. printf("Error creating temporary file!\n");
  278. return;
  279. }
  280.  
  281. currentIndex = 1;
  282. char dateInput[11]; // Moved the declaration outside the switch statement
  283. while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4) {
  284. if (currentIndex == index) {
  285. // Editing logic here
  286. printf("What do you want to edit?\n");
  287. printf("1. Category\n");
  288. printf("2. Amount\n");
  289. printf("3. Date\n");
  290. int editChoice;
  291. printf("Enter your choice: ");
  292. scanf("%d", &editChoice);
  293.  
  294. switch (editChoice) {
  295. case 1:
  296. // Edit category
  297. printf("Choose a new category:\n");
  298. displayCategories();
  299. int categoryNum;
  300. // Input validation for category number
  301. while (true) {
  302. printf("Enter category number: ");
  303. if (scanf("%d", &categoryNum) != 1 || categoryNum < 1 || categoryNum > sizeof(allowedCategories) / sizeof(allowedCategories[0])) {
  304. printf("Invalid category number! Please choose a valid category number.\n");
  305. // Clear input buffer
  306. while (getchar() != '\n');
  307. } else {
  308. strcpy(category, allowedCategories[categoryNum - 1]);
  309. break;
  310. }
  311. }
  312. break;
  313. case 2:
  314. // Edit amount
  315. printf("Enter new amount: ");
  316. while (true) {
  317. if (scanf("%f", &amount) == 1 && amount > 0.0f)
  318. break;
  319. else {
  320. printf("Invalid input! Please enter a valid amount greater than 0.\n");
  321. // Clear input buffer
  322. while (getchar() != '\n');
  323. }
  324. }
  325. break;
  326. case 3:
  327. // Edit date
  328. while (true) {
  329. printf("Enter new date (DD-MM-YYYY): ");
  330. if (scanf("%10s", dateInput) != 1) {
  331. printf("Invalid input! Please enter the date in DD-MM-YYYY format.\n");
  332. // Clear input buffer
  333. while (getchar() != '\n');
  334. continue;
  335. }
  336.  
  337. // Parse date input into day, month, and year components
  338. int day, month, year;
  339. if (sscanf(dateInput, "%d-%d-%d", &day, &month, &year) != 3) {
  340. printf("Invalid date format! Please enter the date in DD-MM-YYYY format.\n");
  341. continue;
  342. }
  343.  
  344. // Validate day, month, and year ranges
  345. if (day < 1 || day > 31 || month < 1 || month > 12 || year < 1900 || year > 9999) {
  346. printf("Invalid date! Please enter a valid date.\n");
  347. continue;
  348. }
  349.  
  350. // Date input is valid
  351. sprintf(date, "%02d-%02d-%04d", day, month, year);
  352. break;
  353. }
  354. break;
  355. default:
  356. printf("Invalid choice! Please try again.\n");
  357. }
  358. }
  359. fprintf(tempFile, "%s %.2f %s %s\n", category, amount, currency, date);
  360. currentIndex++;
  361. }
  362.  
  363. fclose(tempFile);
  364.  
  365. // Remove the old file
  366. remove(filename);
  367.  
  368. // Rename the temporary file to the original filename
  369. rename(tempFilename, filename);
  370.  
  371. // Reopen the file for further operations
  372. file = fopen(filename, "r+");
  373. if (file == NULL) {
  374. printf("Error reopening file!\n");
  375. return;
  376. }
  377.  
  378. printf("Expense edited successfully!\n");
  379. }
  380.  
  381. void deleteExpense(FILE *file, const char *filename) {
  382. // Display current expenses
  383. printf("Current Expenses:\n");
  384.  
  385. // Move file pointer to the beginning
  386.  
  387. char category[50];
  388. float amount;
  389. char currency[4];
  390. char date[20];
  391. int currentIndex = 1;
  392. bool found = false;
  393.  
  394. // Check if there are any expenses in the file
  395. if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
  396. printf("No expenses recorded.\n");
  397. return;
  398. }
  399.  
  400. printf("Index Category Amount Currency Date\n");
  401. do {
  402. printf("%d\t%-15s%.2f\t%-3s\t%s\n", currentIndex, category, amount, currency, date);
  403. currentIndex++;
  404. } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);
  405.  
  406. int index;
  407. printf("Enter the index of the expense you want to delete: ");
  408. scanf("%d", &index);
  409.  
  410. // Move file pointer to the beginning
  411.  
  412. // Create a temporary file to store updated data
  413. char tempFilename[150];
  414. sprintf(tempFilename, "temp_%s", filename);
  415. FILE *tempFile = fopen(tempFilename, "w+");
  416. if (tempFile == NULL) {
  417. printf("Error creating temporary file!\n");
  418. return;
  419. }
  420.  
  421. currentIndex = 1;
  422. while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4) {
  423. if (currentIndex != index)
  424. fprintf(tempFile, "%s %.2f %s %s\n", category, amount, currency, date);
  425. else
  426. found = true;
  427. currentIndex++;
  428. }
  429.  
  430. fclose(tempFile);
  431.  
  432. if (!found) {
  433. printf("Expense not found!\n");
  434. remove(tempFilename); // Delete temporary file
  435. return;
  436. }
  437.  
  438. // Remove the old file
  439. remove(filename);
  440.  
  441. // Rename the temporary file to the original filename
  442. rename(tempFilename, filename);
  443.  
  444. // Reopen the file for further operations
  445. file = fopen(filename, "r+");
  446. if (file == NULL) {
  447. printf("Error reopening file!\n");
  448. return;
  449. }
  450.  
  451. printf("Expense deleted successfully!\n");
  452. }
  453.  
  454. void displayCategories() {
  455. int i;
  456. for (i = 0; i < sizeof(allowedCategories) / sizeof(allowedCategories[0]); i++) {
  457. printf("%d. %s\n", i + 1, allowedCategories[i]);
  458. }
  459. }
  460.  
  461. void categorizeSpending(FILE *file) {
  462. rewind(file); // Move file pointer to the beginning
  463. char category[50];
  464. float amount;
  465. char currency[4];
  466. char date[20];
  467. float categoryTotal[sizeof(allowedCategories) / sizeof(allowedCategories[0])] = {0};
  468.  
  469. // Check if there are any expenses in the file
  470. if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
  471. printf("No expenses recorded.\n");
  472. return;
  473. }
  474.  
  475. // Iterate through expenses and calculate total spending per category
  476. do {
  477. for (int i = 0; i < sizeof(allowedCategories) / sizeof(allowedCategories[0]); i++) {
  478. if (strcmp(category, allowedCategories[i]) == 0) {
  479. categoryTotal[i] += amount;
  480. break;
  481. }
  482. }
  483. } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);
  484.  
  485. // Display total spending per category
  486. printf("Category\tTotal Spending\n");
  487. for (int i = 0; i < sizeof(allowedCategories) / sizeof(allowedCategories[0]); i++) {
  488. printf("%s\t%.2f\n", allowedCategories[i], categoryTotal[i]);
  489. }
  490. }
  491.  
  492. void trackBudget(FILE *file) {
  493. rewind(file); // Move file pointer to the beginning
  494. char category[50];
  495. float amount;
  496. char currency[4];
  497. char date[20];
  498. float total = 0.0f;
  499.  
  500. // Check if there are any expenses in the file
  501. if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
  502. printf("No expenses recorded.\n");
  503. return;
  504. }
  505.  
  506. // Calculate total spending
  507. do {
  508. total += amount;
  509. } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);
  510.  
  511. float budget;
  512. printf("Enter your budget: ");
  513. scanf("%f", &budget);
  514.  
  515. printf("Total spending: $%.2f\n", total);
  516. printf("Budget: $%.2f\n", budget);
  517.  
  518. if (total > budget) {
  519. printf("You have exceeded your budget.\n");
  520. } else {
  521. printf("You are within your budget.\n");
  522. }
  523. }
  524.  
  525. size_t write_callback(char *ptr, size_t size, size_t nmemb, char *data) {
  526. strcat(data, ptr);
  527. return size * nmemb;
  528. }
  529.  
  530. double getExchangeRate(const char *from, const char *to) {
  531. // API request URL for fetching exchange rates
  532. char url[100] = "https://o...content-available-to-author-only...i.com/v6/latest/";
  533. strcat(url, from);
  534. strcat(url, "?symbols=");
  535. strcat(url, to);
  536.  
  537. // Initialize CURL
  538. CURL *curl = curl_easy_init();
  539. if (!curl) {
  540. fprintf(stderr, "Failed to initialize CURL\n");
  541. return -1.0;
  542. }
  543.  
  544. // Data buffer to store API response
  545. char data[100];
  546. data[0] = '\0';
  547.  
  548. // Set CURL options
  549. curl_easy_setopt(curl, CURLOPT_URL, url);
  550. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
  551. curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);
  552.  
  553. // Perform the request
  554. CURLcode res = curl_easy_perform(curl);
  555. if (res != CURLE_OK) {
  556. fprintf(stderr, "Failed to perform CURL request: %s\n", curl_easy_strerror(res));
  557. curl_easy_cleanup(curl);
  558. return -1.0;
  559. }
  560.  
  561. // Cleanup CURL
  562. curl_easy_cleanup(curl);
  563.  
  564. // Parse the JSON response to get the exchange rate
  565. char *ptr = strstr(data, to);
  566. if (!ptr) {
  567. fprintf(stderr, "Failed to parse JSON response\n");
  568. return -1.0;
  569. }
  570. ptr += strlen(to) + 3; // Move pointer to the exchange rate value
  571. return atof(ptr);
  572. }
  573.  
Success #stdin #stdout 0.04s 25600KB
stdin
Standard input is empty
stdout
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <curl/curl.h>

#define BASE_CURRENCY "USD"

// Define the allowed expense categories
const char *allowedCategories[] = {
    "Housing", "Transportation", "Food", "Healthcare", "Utilities", "Debt", 
    "Personal Care", "Entertainment", "Insurance", "Education", "Savings/Investments", 
    "Clothing", "Charity", "Travel", "Miscellaneous"
};

// Function prototypes
void addExpense(FILE *file);
void displayExpensesAndTotal(FILE *file);
void displayExpensesPerMonthAndTotal(FILE *file);
void editExpense(FILE *file, const char *filename);
void deleteExpense(FILE *file, const char *filename);
void displayCategories();
void categorizeSpending(FILE *file);
void trackBudget(FILE *file);
size_t write_callback(char *ptr, size_t size, size_t nmemb, char *data);
double getExchangeRate(const char *from, const char *to);

int main() {
    char first_name[50], last_name[50];
    printf("Enter your first and last name: ");
    scanf("%s %s", first_name, last_name);

    // Create a file with the user's name to store expenses or open existing file if it exists
    char filename[150]; // Assuming a maximum length of 150 characters for the filename
    sprintf(filename, "%s_%s_expenses.txt", first_name, last_name);

    int choice;

    do {
        printf("\nCurrent User: %s %s\n", first_name, last_name);
        printf("Expense Tracker Menu\n");
        printf("1. Add Expense\n");
        printf("2. Display Expenses and Total\n");
        printf("3. Display Expenses per Month and Total\n");
        printf("4. Edit Expense\n");
        printf("5. Delete Expense\n");
        printf("6. Categorize Spending\n");
        printf("7. Track Budget\n");
        printf("8. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        FILE *file = fopen(filename, "a+");
        if (file == NULL) {
            printf("Error opening file!\n");
            return 1;
        }

        switch (choice) {
            case 1:
                addExpense(file);
                fclose(file);
                break;
            case 2:
                displayExpensesAndTotal(file);
                fclose(file);
                break;
            case 3:
                displayExpensesPerMonthAndTotal(file);
                fclose(file);
                break;
            case 4:
                editExpense(file, filename);
                break;
            case 5:
                deleteExpense(file, filename);
                break;
            case 6:
                categorizeSpending(file);
                fclose(file);
                break;
            case 7:
                trackBudget(file);
                fclose(file);
                break;
            case 8:
                printf("Exiting...\n");
                fclose(file); // Close the file before exiting
                break;
            default:
                printf("Invalid choice! Please try again.\n");
        }
    } while (choice != 8);

    return 0;
}

void addExpense(FILE *file) {
    printf("Available Expense Categories:\n");
    displayCategories();
    
    char category[50];
    float amount;
    char date[20];
    char currency[4]; // Assuming currency code is 3 characters long
    
    int categoryNum;
    // Input validation for category number
    while (true) {
        printf("Enter category number: ");
        if (scanf("%d", &categoryNum) != 1 || categoryNum < 1 || categoryNum > sizeof(allowedCategories) / sizeof(allowedCategories[0])) {
            printf("Invalid category number! Please choose a valid category number.\n");
            // Clear input buffer
            while (getchar() != '\n');
        } else {
            strcpy(category, allowedCategories[categoryNum - 1]);
            break;
        }
    }

    // Input validation for amount
    while (true) {
        printf("Enter amount: ");
        if (scanf("%f", &amount) == 1 && amount > 0.0f)
            break;
        else {
            printf("Invalid input! Please enter a valid amount greater than 0.\n");
            // Clear input buffer
            while (getchar() != '\n');
        }
    }

    // Input validation for date format (DD-MM-YYYY)
    char dateInput[11]; // Assuming maximum length of the date input is 10 characters (including null terminator)
    while (true) {
        printf("Enter date (DD-MM-YYYY): ");
        if (scanf("%10s", dateInput) != 1) {
            printf("Invalid input! Please enter the date in DD-MM-YYYY format.\n");
            // Clear input buffer
            while (getchar() != '\n');
            continue;
        }

        // Parse date input into day, month, and year components
        int day, month, year;
        if (sscanf(dateInput, "%d-%d-%d", &day, &month, &year) != 3) {
            printf("Invalid date format! Please enter the date in DD-MM-YYYY format.\n");
            continue;
        }

        // Validate day, month, and year ranges
        if (day < 1 || day > 31 || month < 1 || month > 12 || year < 1900 || year > 9999) {
            printf("Invalid date! Please enter a valid date.\n");
            continue;
        }

        // Date input is valid
        sprintf(date, "%02d-%02d-%04d", day, month, year);
        break;
    }
    
    // Input currency code
    printf("Enter currency code (e.g., USD, EUR): ");
    scanf("%s", currency);

    // Convert currency to base currency (USD)
    double exchangeRate = getExchangeRate(currency, BASE_CURRENCY);
    if (exchangeRate < 0) {
        fprintf(stderr, "Failed to get exchange rate for %s to %s\n", currency, BASE_CURRENCY);
        return;
    }

    // Convert amount to base currency
    amount *= exchangeRate;

    // Save expense to file
    fprintf(file, "%s %.2f %s %s\n", category, amount, BASE_CURRENCY, date);
    printf("Expense added successfully!\n");
}

void displayExpensesAndTotal(FILE *file) {
    rewind(file); // Move file pointer to the beginning
    char category[50];
    float amount;
    char currency[4];
    char date[20];
    float total = 0.0f;
    int expenseCount = 0;

    // Check if there are any expenses in the file
    if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
        printf("No expenses recorded.\n");
        return;
    }

    printf("Index   Category        Amount  Currency    Date\n");
    do {
        printf("%d\t%-15s%.2f\t%-3s\t%s\n", ++expenseCount, category, amount, currency, date);
        total += amount;
    } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);

    printf("\nTotal Expenses: $%.2f\n", total);
}

void displayExpensesPerMonthAndTotal(FILE *file) {
    rewind(file); // Move file pointer to the beginning
    char category[50];
    float amount;
    char currency[4];
    char date[20];
    float total = 0.0f;

    // Buffer to store month and year in MM-YYYY format
    char inputMonthYear[8];

    printf("Enter month and year (MM-YYYY): ");
    scanf("%s", inputMonthYear);

    bool foundExpenses = false;

    while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4) {
        // Extract month and year from the date
        char expenseMonthYear[8];
        strncpy(expenseMonthYear, date + 3, 7); // Extract MM-YYYY from DD-MM-YYYY
        expenseMonthYear[7] = '\0';

        // Check if the extracted month and year match the user-provided input
        if (strcmp(expenseMonthYear, inputMonthYear) == 0) {
            if (!foundExpenses) {
                printf("Category\tAmount\tCurrency\tDate\n");
                foundExpenses = true;
            }
            printf("%-15s%.2f\t%-3s\t%s\n", category, amount, currency, date);
            total += amount;
        }
    }

    if (!foundExpenses) {
        printf("No expenses for %s\n", inputMonthYear);
        return;
    }

    printf("\nTotal Expenses for %s: $%.2f\n", inputMonthYear, total);
}

void editExpense(FILE *file, const char *filename) {
    // Display current expenses
    printf("Current Expenses:\n");

    // Move file pointer to the beginning
    rewind(file);

    char category[50];
    float amount;
    char currency[4];
    char date[20];
    int currentIndex = 1;
    bool found = false;

    // Check if there are any expenses in the file
    if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
        printf("No expenses recorded.\n");
        return;
    }

    printf("Index   Category        Amount  Currency    Date\n");
    do {
        printf("%d\t%-15s%.2f\t%-3s\t%s\n", currentIndex, category, amount, currency, date);
        currentIndex++;
    } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);

    int index;
    printf("Enter the index of the expense you want to edit: ");
    scanf("%d", &index);

    // Move file pointer to the beginning
    rewind(file);

    // Create a temporary file to store updated data
    char tempFilename[150];
    sprintf(tempFilename, "temp_%s", filename);
    FILE *tempFile = fopen(tempFilename, "w+");
    if (tempFile == NULL) {
        printf("Error creating temporary file!\n");
        return;
    }

    currentIndex = 1;
    char dateInput[11]; // Moved the declaration outside the switch statement
    while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4) {
        if (currentIndex == index) {
            // Editing logic here
            printf("What do you want to edit?\n");
            printf("1. Category\n");
            printf("2. Amount\n");
            printf("3. Date\n");
            int editChoice;
            printf("Enter your choice: ");
            scanf("%d", &editChoice);

            switch (editChoice) {
                case 1:
                    // Edit category
                    printf("Choose a new category:\n");
                    displayCategories();
                    int categoryNum;
                    // Input validation for category number
                    while (true) {
                        printf("Enter category number: ");
                        if (scanf("%d", &categoryNum) != 1 || categoryNum < 1 || categoryNum > sizeof(allowedCategories) / sizeof(allowedCategories[0])) {
                            printf("Invalid category number! Please choose a valid category number.\n");
                            // Clear input buffer
                            while (getchar() != '\n');
                        } else {
                            strcpy(category, allowedCategories[categoryNum - 1]);
                            break;
                        }
                    }
                    break;
                case 2:
                    // Edit amount
                    printf("Enter new amount: ");
                    while (true) {
                        if (scanf("%f", &amount) == 1 && amount > 0.0f)
                            break;
                        else {
                            printf("Invalid input! Please enter a valid amount greater than 0.\n");
                            // Clear input buffer
                            while (getchar() != '\n');
                        }
                    }
                    break;
                case 3:
                    // Edit date
                    while (true) {
                        printf("Enter new date (DD-MM-YYYY): ");
                        if (scanf("%10s", dateInput) != 1) {
                            printf("Invalid input! Please enter the date in DD-MM-YYYY format.\n");
                            // Clear input buffer
                            while (getchar() != '\n');
                            continue;
                        }

                        // Parse date input into day, month, and year components
                        int day, month, year;
                        if (sscanf(dateInput, "%d-%d-%d", &day, &month, &year) != 3) {
                            printf("Invalid date format! Please enter the date in DD-MM-YYYY format.\n");
                            continue;
                        }

                        // Validate day, month, and year ranges
                        if (day < 1 || day > 31 || month < 1 || month > 12 || year < 1900 || year > 9999) {
                            printf("Invalid date! Please enter a valid date.\n");
                            continue;
                        }

                        // Date input is valid
                        sprintf(date, "%02d-%02d-%04d", day, month, year);
                        break;
                    }
                    break;
                default:
                    printf("Invalid choice! Please try again.\n");
            }
        }
        fprintf(tempFile, "%s %.2f %s %s\n", category, amount, currency, date);
        currentIndex++;
    }

    fclose(file);
    fclose(tempFile);

    // Remove the old file
    remove(filename);

    // Rename the temporary file to the original filename
    rename(tempFilename, filename);

    // Reopen the file for further operations
    file = fopen(filename, "r+");
    if (file == NULL) {
        printf("Error reopening file!\n");
        return;
    }

    printf("Expense edited successfully!\n");
}

void deleteExpense(FILE *file, const char *filename) {
    // Display current expenses
    printf("Current Expenses:\n");

    // Move file pointer to the beginning
    rewind(file);

    char category[50];
    float amount;
    char currency[4];
    char date[20];
    int currentIndex = 1;
    bool found = false;

    // Check if there are any expenses in the file
    if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
        printf("No expenses recorded.\n");
        return;
    }

    printf("Index   Category        Amount  Currency    Date\n");
    do {
        printf("%d\t%-15s%.2f\t%-3s\t%s\n", currentIndex, category, amount, currency, date);
        currentIndex++;
    } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);

    int index;
    printf("Enter the index of the expense you want to delete: ");
    scanf("%d", &index);

    // Move file pointer to the beginning
    rewind(file);

    // Create a temporary file to store updated data
    char tempFilename[150];
    sprintf(tempFilename, "temp_%s", filename);
    FILE *tempFile = fopen(tempFilename, "w+");
    if (tempFile == NULL) {
        printf("Error creating temporary file!\n");
        return;
    }

    currentIndex = 1;
    while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4) {
        if (currentIndex != index)
            fprintf(tempFile, "%s %.2f %s %s\n", category, amount, currency, date);
        else
            found = true;
        currentIndex++;
    }

    fclose(file);
    fclose(tempFile);

    if (!found) {
        printf("Expense not found!\n");
        remove(tempFilename); // Delete temporary file
        return;
    }

    // Remove the old file
    remove(filename);

    // Rename the temporary file to the original filename
    rename(tempFilename, filename);

    // Reopen the file for further operations
    file = fopen(filename, "r+");
    if (file == NULL) {
        printf("Error reopening file!\n");
        return;
    }

    printf("Expense deleted successfully!\n");
}

void displayCategories() {
    int i;
    for (i = 0; i < sizeof(allowedCategories) / sizeof(allowedCategories[0]); i++) {
        printf("%d. %s\n", i + 1, allowedCategories[i]);
    }
}

void categorizeSpending(FILE *file) {
    rewind(file); // Move file pointer to the beginning
    char category[50];
    float amount;
    char currency[4];
    char date[20];
    float categoryTotal[sizeof(allowedCategories) / sizeof(allowedCategories[0])] = {0};

    // Check if there are any expenses in the file
    if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
        printf("No expenses recorded.\n");
        return;
    }

    // Iterate through expenses and calculate total spending per category
    do {
        for (int i = 0; i < sizeof(allowedCategories) / sizeof(allowedCategories[0]); i++) {
            if (strcmp(category, allowedCategories[i]) == 0) {
                categoryTotal[i] += amount;
                break;
            }
        }
    } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);

    // Display total spending per category
    printf("Category\tTotal Spending\n");
    for (int i = 0; i < sizeof(allowedCategories) / sizeof(allowedCategories[0]); i++) {
        printf("%s\t%.2f\n", allowedCategories[i], categoryTotal[i]);
    }
}

void trackBudget(FILE *file) {
    rewind(file); // Move file pointer to the beginning
    char category[50];
    float amount;
    char currency[4];
    char date[20];
    float total = 0.0f;

    // Check if there are any expenses in the file
    if (fscanf(file, "%s %f %s %s", category, &amount, currency, date) != 4) {
        printf("No expenses recorded.\n");
        return;
    }

    // Calculate total spending
    do {
        total += amount;
    } while (fscanf(file, "%s %f %s %s", category, &amount, currency, date) == 4);

    float budget;
    printf("Enter your budget: ");
    scanf("%f", &budget);

    printf("Total spending: $%.2f\n", total);
    printf("Budget: $%.2f\n", budget);

    if (total > budget) {
        printf("You have exceeded your budget.\n");
    } else {
        printf("You are within your budget.\n");
    }
}

size_t write_callback(char *ptr, size_t size, size_t nmemb, char *data) {
    strcat(data, ptr);
    return size * nmemb;
}

double getExchangeRate(const char *from, const char *to) {
    // API request URL for fetching exchange rates
    char url[100] = "https://o...content-available-to-author-only...i.com/v6/latest/";
    strcat(url, from);
    strcat(url, "?symbols=");
    strcat(url, to);

    // Initialize CURL
    CURL *curl = curl_easy_init();
    if (!curl) {
        fprintf(stderr, "Failed to initialize CURL\n");
        return -1.0;
    }

    // Data buffer to store API response
    char data[100];
    data[0] = '\0';

    // Set CURL options
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, data);

    // Perform the request
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "Failed to perform CURL request: %s\n", curl_easy_strerror(res));
        curl_easy_cleanup(curl);
        return -1.0;
    }

    // Cleanup CURL
    curl_easy_cleanup(curl);

    // Parse the JSON response to get the exchange rate
    char *ptr = strstr(data, to);
    if (!ptr) {
        fprintf(stderr, "Failed to parse JSON response\n");
        return -1.0;
    }
    ptr += strlen(to) + 3; // Move pointer to the exchange rate value
    return atof(ptr);
}