diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0f5317a --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +all: snconverter + +WARNINGS = -Wall +DEBUG = -ggdb -fno-omit-frame-pointer +OPTIMIZE = -O2 +OPTS = -lm + +snconverter: Makefile snconverter.c + $(CC) -o $@ $(WARNINGS) $(DEBUG) $(OPTIMIZE) $(OPTS) snconverter.c + +clean: + rm -f snconverter + +install: + echo "Installing is not supported" + +run: + ./snconverter + diff --git a/README.md b/README.md index 8122ee9..0b0388f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,128 @@ # snconverter -A simple and efficient command line numeric system conversion tool. Supports binary, decimal, hexadecimal and octal. + +## Table of Contents + +- [Introduction](#introduction) +- [Building](#building) +- [Usage](#usage) +- [Options](#options) +- [Examples](#examples) +- [Notes](#examples) + +## Introduction + +**snconverter** is a command-line utility designed to convert numbers between +different systems: decimal, binary, hexadecimal, and octal. It supports +conversion from any of these number systems to any other, providing a versatile +tool for developers, students, and anyone needing to perform such conversions +regularly. + +## Building + +This tool is provided as source code and can be built using `make`. By just +typing make in the terminal within the code's directory: + +```bash +make +``` + +You should now have an executable named `snconverter`. You can copy it to a +location in your PATH for easy access. + +## Usage + +To use the `snconverter`, run the executable from the command line with the +appropriate options. + +```bash +./snconverter [OPTIONS] +``` + +## Options + +**snconverter** accepts the following options: + +- `-d`, `--decimal `: + - Specify the input value is in decimal. + +- `-b`, `--binary `: + - Specify the input value is in binary. + +- `-x`, `--hex `: + - Specify the input value is in hexadecimal. + +- `-o`, `--octal `: + - Specify the input value is in octal. + +- `-h`, `--help`: + - Display the help message and exit. + +- `-v`, `--version`: + - Display the program version and exit. + +## Examples + +1. Convert a decimal number to binary, hexadecimal, and octal: + +```bash +./snconverter -d 255 +``` + +Output: + +``` +Binary: 11111111 +Hexadecimal: FF +Octal: 377 +``` + +2. Convert a binary number to decimal, hexadecimal, and octal: + +```bash +./snconverter -b 11010101 +``` + +Output: + +``` +Decimal: 213 +Hexadecimal: D5 +Octal: 325 +``` + +3. Convert a hexadecimal number to decimal, binary, and octal: + +```bash +./snconverter -x 1A3F +``` + +Output: + +``` +Decimal: 6719 +Binary: 1101000111111 +Octal: 15177 +``` + +4. Display help message: + +```bash +./snconverter -h +``` + +This will display detailed usage instructions and available options. + +5. Display version: + +```bash +./snconverter -v +``` + +This will show the current version of the program. + +## Notes + +- Input values must be valid numbers in their respective systems (e.g., no + letters in binary). +- This tool does not currently support floating-point numbers or numbers beyond + the range of standard 32-bit integers. diff --git a/snconverter.c b/snconverter.c new file mode 100644 index 0000000..cef1418 --- /dev/null +++ b/snconverter.c @@ -0,0 +1,200 @@ +/* + * snconverter.c + * + * Copyright 2024 Clay Gomera + * + * 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 3 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, see . + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include +#include +#include +#include + +#define NAME "snconverter" +#define VERSION 0.1 + +void decimalToBinary(int num, char* result); +void decimalToHexadecimal(int num, char* result); +void decimalToOctal(int num, char* result); +void binaryToDecimal(const char* num, int* result); +void binaryToHexadecimal(const char* num, char* result); +void binaryToOctal(const char* num, char* result); +void hexadecimalToDecimal(const char* num, int* result); +void hexadecimalToBinary(const char* num, char* result); +void hexadecimalToOctal(const char* num, char* result); +void octalToDecimal(const char* num, int* result); +void octalToBinary(const char* num, char* result); +void octalToHexadecimal(const char* num, char* result); +void reverseString(char* str); +void displayHelp(); +void displayVersion(); + +int main(int argc, char** argv) { + int option; + char result[100]; + int decimal_result; + + if (argc == 1) { + fprintf(stderr, "No argument provided.\n"); + displayHelp(); + return EXIT_FAILURE; + } + + static const char* short_options = "d:b:x:o:abchv"; + static struct option long_options[] = { + {"decimal", required_argument, NULL, 'd'}, + {"binary", required_argument, NULL, 'b'}, + {"hex", required_argument, NULL, 'x'}, + {"octal", required_argument, NULL, 'o'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {NULL, 0, NULL, 0} + }; + + while ((option = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { + switch (option) { + case 'd': + decimalToBinary(atoi(optarg), result); + printf("Binary: %s\n", result); + decimalToHexadecimal(atoi(optarg), result); + printf("Hexadecimal: %s\n", result); + decimalToOctal(atoi(optarg), result); + printf("Octal: %s\n", result); + break; + case 'b': + binaryToDecimal(optarg, &decimal_result); + printf("Decimal: %d\n", decimal_result); + binaryToHexadecimal(optarg, result); + printf("Hexadecimal: %s\n", result); + binaryToOctal(optarg, result); + printf("Octal: %s\n", result); + break; + case 'x': + hexadecimalToDecimal(optarg, &decimal_result); + printf("Decimal: %d\n", decimal_result); + hexadecimalToBinary(optarg, result); + printf("Binary: %s\n", result); + hexadecimalToOctal(optarg, result); + printf("Octal: %s\n", result); + break; + case 'o': + octalToDecimal(optarg, &decimal_result); + printf("Decimal: %d\n", decimal_result); + octalToBinary(optarg, result); + printf("Binary: %s\n", result); + octalToHexadecimal(optarg, result); + printf("Hexadecimal: %s\n", result); + break; + case 'h': + displayHelp(); + return EXIT_SUCCESS; + case 'v': + displayVersion(); + return EXIT_SUCCESS; + case '?': + default: + fprintf(stderr, "Use '-h, --help' for help.\n"); + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} + +void decimalToBinary(int num, char* result) { + int index = 0; + while (num > 0) { + result[index++] = (num % 2) + '0'; + num /= 2; + } + result[index] = '\0'; + reverseString(result); // Reverse the string to get the correct order +} + +void decimalToHexadecimal(int num, char* result) { + sprintf(result, "%X", num); +} + +void decimalToOctal(int num, char* result) { + sprintf(result, "%o", num); +} + +void binaryToDecimal(const char* num, int* result) { + *result = strtol(num, NULL, 2); +} + +void binaryToHexadecimal(const char* num, char* result) { + int decimal = strtol(num, NULL, 2); + sprintf(result, "%X", decimal); +} + +void binaryToOctal(const char* num, char* result) { + int decimal = strtol(num, NULL, 2); + sprintf(result, "%o", decimal); +} + +void hexadecimalToDecimal(const char* num, int* result) { + *result = strtol(num, NULL, 16); +} + +void hexadecimalToBinary(const char* num, char* result) { + int decimal = strtol(num, NULL, 16); + decimalToBinary(decimal, result); +} + +void hexadecimalToOctal(const char* num, char* result) { + int decimal = strtol(num, NULL, 16); + decimalToOctal(decimal, result); +} + +void octalToDecimal(const char* num, int* result) { + *result = strtol(num, NULL, 8); +} + +void octalToBinary(const char* num, char* result) { + int decimal = strtol(num, NULL, 8); + decimalToBinary(decimal, result); +} + +void octalToHexadecimal(const char* num, char* result) { + int decimal = strtol(num, NULL, 8); + decimalToHexadecimal(decimal, result); +} + +void reverseString(char* str) { + int n = strlen(str); + for (int i = 0; i < n / 2; i++) { + char temp = str[i]; + str[i] = str[n - i - 1]; + str[n - i - 1] = temp; + } +} + +void displayHelp() { + printf("Usage: %s -[d|b|h|o] --[tob|tod|toh|too]\n", NAME); + printf("Options:\n"); + printf("\t-d, --decimal\t\tInput is in decimal\n"); + printf("\t-b, --binary\t\tInput is in binary\n"); + printf("\t-h, --hex\t\tInput is in hexadecimal\n"); + printf("\t-o, --octal\t\tInput is in octal\n"); + printf("\t-h, --help\t\tDisplay this help message and exit.\n"); + printf("\t-v, --version\t\tDisplay version and exit.\n"); +} + +void displayVersion() { + printf("%s version %.1f\n", NAME, VERSION); +}