From ab12cec3619c8b8c4d156f7d8bacffe48c17e305 Mon Sep 17 00:00:00 2001 From: mrkmntal Date: Thu, 26 Mar 2026 22:23:37 -0400 Subject: [PATCH] Initial Commit of sccash --- .gitignore | 1 + README.md | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++ sccash.1 | 157 ++++++++++++++++++++++++++++++++++++++ sccash.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 575 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 sccash.1 create mode 100644 sccash.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d7f83c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +sccash diff --git a/README.md b/README.md new file mode 100644 index 0000000..8432a2c --- /dev/null +++ b/README.md @@ -0,0 +1,220 @@ +# sccash - Simple C Cash + +A lightweight, fast CLI currency converter written in C for USD, JPY, and EUR conversions. + +## Features + +- **Dual Mode Operation**: Command-line arguments for scripting, interactive prompts for manual use +- **Table Formatted Output**: Clean, readable conversion results +- **Lightweight**: No external dependencies, standard C library only +- **Fast**: Compiles to a small, efficient binary +- **Error Handling**: Clear error messages for invalid inputs + +## Exchange Rates (as of March 26, 2026) + +- **1 USD** = 159.67 JPY +- **1 USD** = 0.866 EUR +- **1 EUR** = 184.20 JPY + +*Note: These rates are hardcoded and may not reflect current market rates.* + +## Compilation + +```bash +gcc -o sccash sccash.c -Wall -O2 +``` + +Or for a static binary: +```bash +gcc -o sccash sccash.c -Wall -O2 -static +``` + +## Installation + +### Option 1: Local Installation +```bash +# Compile first +gcc -o sccash sccash.c -Wall -O2 + +# Copy to local bin directory +mkdir -p ~/bin +cp sccash ~/bin/ + +# Add to PATH if not already +export PATH="$HOME/bin:$PATH" +``` + +### Option 2: System-wide Installation +```bash +# Compile first +gcc -o sccash sccash.c -Wall -O2 + +# Install to system path (requires sudo) +sudo cp sccash /usr/local/bin/ + +# Verify installation +sccash --help +``` + +## Usage + +### CLI Mode + +Pass three arguments: `amount`, `from_currency`, and `to_currency`. + +```bash +./sccash +``` + +**Examples:** + +```bash +# Convert 100 USD to JPY +./sccash 100 USD JPY + +# Convert 50 EUR to USD +./sccash 50 EUR USD + +# Convert 1000 JPY to EUR +./sccash 1000 JPY EUR +``` + +### Interactive Mode + +Run without arguments for interactive prompts: + +```bash +./sccash +``` + +Example session: +``` +=== sccash - Simple C Cash === + +Available currencies: USD, JPY, EUR + +Enter amount: 100 +Convert from (USD/JPY/EUR): USD +Convert to (USD/JPY/EUR): JPY + ++--------+---------------+--------+----------------+ +| FROM | AMOUNT | TO | CONVERTED | ++--------+---------------+--------+----------------+ +| USD | 100.00 | JPY | 15967.00 | ++--------+---------------+--------+----------------+ + +Show all conversions? (y/n): y + ++--------+---------------+--------+----------------+ +| FROM | AMOUNT | TO | CONVERTED | ++--------+---------------+--------+----------------+ +| USD | 100.00 | JPY | 15967.00 | +| USD | 100.00 | EUR | 86.60 | ++--------+---------------+--------+----------------+ + +Exchange Rates (as of March 26, 2026): + 1 USD = 159.67 JPY + 1 USD = 0.866 EUR + 1 EUR = 184.20 JPY +``` + +## Sample Output + +```bash +$ ./sccash 250 USD EUR + ++--------+---------------+--------+----------------+ +| FROM | AMOUNT | TO | CONVERTED | ++--------+---------------+--------+----------------+ +| USD | 250.00 | EUR | 216.50 | ++--------+---------------+--------+----------------+ +``` + +## Error Handling + +```bash +$ ./sccash 100 GBP USD +Error: Invalid source currency 'GBP' +Available: USD, JPY, EUR + +$ ./sccash +=== sccash - Simple C Cash === + +Available currencies: USD, JPY, EUR + +Enter amount: invalid +Error: Invalid amount +``` + +## Architecture + +sccash uses USD as the base currency for all conversions: + +1. Convert source amount to USD +2. Convert USD amount to target currency + +This approach minimizes rounding errors and keeps the code simple and maintainable. + +## Currencies Supported + +- **USD** - United States Dollar +- **JPY** - Japanese Yen +- **EUR** - Euro + +Currency codes are case-insensitive (usd, USD, Usd all work). + +## Technical Details + +- **Lines of Code**: ~200 +- **Dependencies**: Standard C library only (stdio.h, stdlib.h, string.h, ctype.h) +- **Memory Usage**: Minimal - uses only the stack +- **Output Format**: Fixed-width table with 2 decimal precision + +## Building for Different Platforms + +### Linux +```bash +gcc -o sccash sccash.c -Wall -O2 +``` + +### macOS +```bash +clang -o sccash sccash.c -Wall -O2 +``` + +### Windows (MinGW) +```bash +gcc -o sccash.exe sccash.c -Wall -O2 +``` + +## License + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +## Contributing + +This is a simple, focused tool. Contributions should maintain the design goals: +- Keep it lightweight +- No external dependencies +- Simple, readable code +- Clear error messages + +## Author + +Created with simplicity and performance in mind. + +--- + +**Note**: Currency values fluctuate constantly. The exchange rates in this tool are fixed as of March 26, 2026. For real-time rates, consider using a service with API integration. diff --git a/sccash.1 b/sccash.1 new file mode 100644 index 0000000..7b3c432 --- /dev/null +++ b/sccash.1 @@ -0,0 +1,157 @@ +.TH SCCASH 1 "March 2026" "sccash 1.0" "User Commands" +.SH NAME +sccash \- Simple C Cash currency converter +.SH SYNOPSIS +.B sccash +.RI [ amount from_currency to_currency ] +.SH DESCRIPTION +.B sccash +is a lightweight, fast CLI currency converter written in C that supports +conversions between USD (US Dollar), JPY (Japanese Yen), and EUR (Euro). +.PP +The program operates in two modes: +.IP \(bu 2 +.B Command-line mode: +Pass arguments directly for quick conversions and scripting +.IP \(bu 2 +.B Interactive mode: +Run without arguments for guided prompts +.PP +All conversions are performed using USD as the base currency to minimize +rounding errors. Results are displayed in a clean table format with +2 decimal precision. +.SH ARGUMENTS +.TP +.B amount +The numeric value to convert. Must be a positive number. +.TP +.B from_currency +Source currency code. Accepted values: USD, JPY, EUR (case-insensitive). +.TP +.B to_currency +Target currency code. Accepted values: USD, JPY, EUR (case-insensitive). +.SH OPTIONS +.TP +.B \-\-help +Display usage information and exit. +.SH EXAMPLES +.TP +Convert 100 USD to JPY: +.B sccash 100 USD JPY +.TP +Convert 50 EUR to USD: +.B sccash 50 EUR USD +.TP +Convert 1000 JPY to EUR: +.B sccash 1000 JPY EUR +.TP +Start interactive mode: +.B sccash +.PP +Example output: +.PP +.nf ++--------+---------------+--------+----------------+ +| FROM | AMOUNT | TO | CONVERTED | ++--------+---------------+--------+----------------+ +| USD | 100.00 | JPY | 15967.00 | ++--------+---------------+--------+----------------+ +.fi +.SH INTERACTIVE MODE +When run without arguments, sccash enters interactive mode and prompts for: +.IP 1. 4 +Amount to convert +.IP 2. 4 +Source currency (USD/JPY/EUR) +.IP 3. 4 +Target currency (USD/JPY/EUR) +.IP 4. 4 +Option to display all possible conversions from the source currency +.PP +Interactive mode is useful for one-off conversions and exploring different +conversion options. +.SH EXCHANGE RATES +The following exchange rates are hardcoded as of March 26, 2026: +.IP \(bu 2 +1 USD = 159.67 JPY +.IP \(bu 2 +1 USD = 0.866 EUR +.IP \(bu 2 +1 EUR = 184.20 JPY +.PP +.B Important: +These rates are fixed and do not update automatically. They may not reflect +current market rates. This tool is designed for quick estimates and personal +use, not for financial trading or time-sensitive conversions. +.SH EXIT STATUS +.TP +.B 0 +Successful conversion or help display +.TP +.B 1 +Error occurred (invalid amount, invalid currency, or missing arguments) +.SH FILES +No configuration files are used. Exchange rates are compiled directly into +the binary. +.SH ENVIRONMENT +No environment variables are used. +.SH COMPILATION +To compile sccash from source: +.PP +.B gcc -o sccash sccash.c -Wall -O2 +.PP +For a static binary: +.PP +.B gcc -o sccash sccash.c -Wall -O2 -static +.SH INSTALLATION +Install the binary to your local bin: +.PP +.B mkdir -p ~/bin && cp sccash ~/bin/ +.PP +Or install system-wide: +.PP +.B sudo cp sccash /usr/local/bin/ +.SH NOTES +Currency codes are case-insensitive. The following are all equivalent: +.BR USD , +.BR usd , +.BR Usd , +.BR usD . +.PP +The program validates all inputs and provides clear error messages for: +.IP \(bu 2 +Non-numeric or negative amounts +.IP \(bu 2 +Invalid currency codes +.IP \(bu 2 +Missing command-line arguments +.SH BUGS +The exchange rates are static and compiled into the binary. They do not +update automatically with market changes. For real-time currency conversion, +consider using a service with API integration. +.PP +Report bugs at: https://github.com/yourusername/sccash/issues +.SH SEE ALSO +.BR bc (1), +.BR units (1), +.BR convert (1) +.SH AUTHOR +Written by markmental (Mark Robillard Jr). +.SH COPYRIGHT +Copyright (C) 2026 markmental (Mark Robillard Jr). +.PP +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +.PP +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +.PP +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +.SH VERSION +sccash 1.0 (March 2026) diff --git a/sccash.c b/sccash.c new file mode 100644 index 0000000..0cb5f92 --- /dev/null +++ b/sccash.c @@ -0,0 +1,197 @@ +/* + * sccash - Simple C Cash + * A lightweight CLI currency converter for USD, JPY, and EUR + * Compile: gcc -o sccash sccash.c + */ + +#include +#include +#include +#include + +#define RATE_USD_JPY 159.67 +#define RATE_USD_EUR 0.866 +#define RATE_EUR_JPY 184.20 + +typedef enum { + CURRENCY_USD, + CURRENCY_JPY, + CURRENCY_EUR, + CURRENCY_INVALID +} Currency; + +const char* currency_names[] = {"USD", "JPY", "EUR"}; + +Currency parse_currency(const char* input) { + char upper[4] = {0}; + for (int i = 0; i < 3 && input[i]; i++) { + upper[i] = toupper(input[i]); + } + + if (strcmp(upper, "USD") == 0) return CURRENCY_USD; + if (strcmp(upper, "JPY") == 0) return CURRENCY_JPY; + if (strcmp(upper, "EUR") == 0) return CURRENCY_EUR; + return CURRENCY_INVALID; +} + +double convert_to_usd(double amount, Currency from) { + switch (from) { + case CURRENCY_USD: return amount; + case CURRENCY_JPY: return amount / RATE_USD_JPY; + case CURRENCY_EUR: return amount / RATE_USD_EUR; + default: return 0.0; + } +} + +double convert_from_usd(double usd_amount, Currency to) { + switch (to) { + case CURRENCY_USD: return usd_amount; + case CURRENCY_JPY: return usd_amount * RATE_USD_JPY; + case CURRENCY_EUR: return usd_amount * RATE_USD_EUR; + default: return 0.0; + } +} + +double convert_currency(double amount, Currency from, Currency to) { + if (from == to) return amount; + double usd_amount = convert_to_usd(amount, from); + return convert_from_usd(usd_amount, to); +} + +void print_table_header(void) { + printf("+--------+---------------+--------+----------------+\n"); + printf("| FROM | AMOUNT | TO | CONVERTED |\n"); + printf("+--------+---------------+--------+----------------+\n"); +} + +void print_table_row(const char* from, double amount, const char* to, double converted) { + printf("| %-6s | %13.2f | %-6s | %14.2f |\n", from, amount, to, converted); +} + +void print_table_footer(void) { + printf("+--------+---------------+--------+----------------+\n"); +} + +void print_all_conversions(double amount, Currency from) { + printf("\n"); + print_table_header(); + + for (int i = 0; i < 3; i++) { + if (i != from) { + Currency to = (Currency)i; + double result = convert_currency(amount, from, to); + print_table_row(currency_names[from], amount, currency_names[to], result); + } + } + + print_table_footer(); + printf("\nExchange Rates (as of March 26, 2026):\n"); + printf(" 1 USD = %.2f JPY\n", RATE_USD_JPY); + printf(" 1 USD = %.3f EUR\n", RATE_USD_EUR); + printf(" 1 EUR = %.2f JPY\n", RATE_EUR_JPY); + printf("\n"); +} + +void interactive_mode(void) { + char from_input[10], to_input[10]; + double amount; + Currency from, to; + + printf("\n=== sccash - Simple C Cash ===\n\n"); + printf("Available currencies: USD, JPY, EUR\n\n"); + + printf("Enter amount: "); + if (scanf("%lf", &amount) != 1 || amount < 0) { + fprintf(stderr, "Error: Invalid amount\n"); + return; + } + + printf("Convert from (USD/JPY/EUR): "); + scanf("%9s", from_input); + from = parse_currency(from_input); + + if (from == CURRENCY_INVALID) { + fprintf(stderr, "Error: Invalid currency '%s'\n", from_input); + return; + } + + printf("Convert to (USD/JPY/EUR): "); + scanf("%9s", to_input); + to = parse_currency(to_input); + + if (to == CURRENCY_INVALID) { + fprintf(stderr, "Error: Invalid currency '%s'\n", to_input); + return; + } + + if (from == to) { + printf("\nResult: %.2f %s (same currency)\n", amount, currency_names[from]); + return; + } + + double result = convert_currency(amount, from, to); + + printf("\n"); + print_table_header(); + print_table_row(currency_names[from], amount, currency_names[to], result); + print_table_footer(); + printf("\n"); + + printf("Show all conversions? (y/n): "); + char show_all[10]; + scanf("%9s", show_all); + if (show_all[0] == 'y' || show_all[0] == 'Y') { + print_all_conversions(amount, from); + } +} + +void cli_mode(int argc, char* argv[]) { + if (argc < 4) { + fprintf(stderr, "Usage: %s \n", argv[0]); + fprintf(stderr, " amount: numeric value to convert\n"); + fprintf(stderr, " from: source currency (USD, JPY, EUR)\n"); + fprintf(stderr, " to: target currency (USD, JPY, EUR)\n\n"); + fprintf(stderr, "Example: %s 100 USD JPY\n", argv[0]); + fprintf(stderr, "Or run without arguments for interactive mode\n"); + exit(1); + } + + double amount = atof(argv[1]); + if (amount <= 0) { + fprintf(stderr, "Error: Invalid amount '%s'\n", argv[1]); + exit(1); + } + + Currency from = parse_currency(argv[2]); + Currency to = parse_currency(argv[3]); + + if (from == CURRENCY_INVALID) { + fprintf(stderr, "Error: Invalid source currency '%s'\n", argv[2]); + fprintf(stderr, "Available: USD, JPY, EUR\n"); + exit(1); + } + + if (to == CURRENCY_INVALID) { + fprintf(stderr, "Error: Invalid target currency '%s'\n", argv[3]); + fprintf(stderr, "Available: USD, JPY, EUR\n"); + exit(1); + } + + double result = convert_currency(amount, from, to); + + printf("\n"); + print_table_header(); + print_table_row(currency_names[from], amount, currency_names[to], result); + print_table_footer(); + printf("\n"); +} + +int main(int argc, char* argv[]) { + if (argc == 1) { + interactive_mode(); + } else { + cli_mode(argc, argv); + } + + return 0; +}