C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
amort.c
Go to the documentation of this file.
1/** @file amort.c
2 @brief Installment Loan Amortization
3 @author Bill Waller
4 Copyright (c) 2026
5 MIT License
6 billxwaller@gmail.com
7 @date 2026-05-05
8 */
9#define _GNU_SOURCE
10#include <locale.h>
11#include <stdbool.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <time.h>
16#include <unistd.h>
17char month[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
18 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
19typedef struct {
20 double pv;
21 double pmt;
22 double i;
23 double n;
24 double interest;
25 double principal;
26 double year_total_interest;
27} Amort;
28void print_totals(Amort *);
29
30int main(int argc, char **argv) {
31 setlocale(LC_NUMERIC, "");
32 if (argc > 1 &&
33 ((strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) ||
34 argc < 5)) {
35 printf("Usage: amort [present_value][number_of_payments]"
36 "[interest_rate][payment_amount][yyyy-mm-dd]\n\n");
37 exit(EXIT_SUCCESS);
38 }
39 struct tm tm;
40 Amort *amort = malloc(sizeof(Amort));
41 sscanf(argv[1], "%lf", &amort->pv);
42 sscanf(argv[2], "%lf", &amort->n);
43 sscanf(argv[3], "%lf", &amort->i);
44 sscanf(argv[4], "%lf", &amort->pmt);
45 if (amort->pv == 0 || amort->n == 0 || amort->i == 0 || amort->pmt == 0 ||
46 argv[5][0] == '\0') {
47 fprintf(stderr, "Error: All arguments must be non-zero.\n");
48 exit(EXIT_FAILURE);
49 }
50 amort->interest = amort->pv * amort->i / 1200;
51 if (amort->interest > amort->pmt) {
52 fprintf(stderr, "Error: Payment amount less than interest\n");
53 exit(EXIT_FAILURE);
54 }
55 memset(&tm, 0, sizeof(tm));
56 if (strptime(argv[5], "%Y-%m-%d", &tm) == NULL)
57 if (strptime(argv[5], "%Y%m%d", &tm) == NULL)
58 printf("Error: Invalid date format. Use yyyy-mm-dd or yyyymmdd.\n"),
59 exit(EXIT_FAILURE);
60 amort->year_total_interest = 0;
61
62 printf("First Payment: %04d-%02d-%02d\n\n", tm.tm_year + 1900,
63 tm.tm_mon + 1, tm.tm_mday);
64 printf(" Per Mth Year Balance Payment Principal Interest\n");
65 printf("---- --- ---- ------------ ---------- ---------- ----------\n");
66 int m = 0;
67 for (int x = 0; x < amort->n; x++) {
68 if (amort->pv <= 0)
69 break;
70 m = (x + tm.tm_mon) % 12;
71 int y = ((x + tm.tm_mon) / 12) + tm.tm_year + 1900;
72 amort->interest = amort->pv * amort->i / 1200;
73 amort->year_total_interest += amort->interest;
74 if (amort->pv + amort->interest < amort->pmt) {
75 amort->pmt = amort->pv + amort->interest;
76 amort->principal = amort->pv;
77 } else
78 amort->principal = amort->pmt - amort->interest;
79 amort->pv -= amort->principal;
80 printf("%4d %4s %4d %'12.2f %'10.2f %'10.2f %'10.2f\n", x + 1, month[m],
81 y, amort->pv, amort->pmt, amort->principal, amort->interest);
82 if (m == 11)
83 print_totals(amort);
84 }
85 if (m != 11)
86 print_totals(amort);
87 free(amort);
88 return EXIT_SUCCESS;
89}
90void print_totals(Amort *amort) {
91 printf(" "
92 "----------\n");
93 printf(" %'10.2f\n",
94 amort->year_total_interest);
95 printf(" "
96 "==========\n\n");
97 amort->year_total_interest = 0;
98}
int main(int argc, char **argv)
Definition amort.c:30
void print_totals(Amort *)
Definition amort.c:90
char month[12][4]
Definition amort.c:17