Initial Commit of sccash
This commit is contained in:
commit
ab12cec361
4 changed files with 575 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
sccash
|
||||
220
README.md
Normal file
220
README.md
Normal file
|
|
@ -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 <amount> <from> <to>
|
||||
```
|
||||
|
||||
**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.
|
||||
157
sccash.1
Normal file
157
sccash.1
Normal file
|
|
@ -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)
|
||||
197
sccash.c
Normal file
197
sccash.c
Normal file
|
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#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 <amount> <from> <to>\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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue