From 426438db24004c1cf9835b8e57e32ecbe916d606 Mon Sep 17 00:00:00 2001 From: Joursoir Date: Sat, 6 Feb 2021 16:01:26 +0000 Subject: refactor roman to arabic algorithm, update few options, able to work with program --- snc.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- snc.h | 2 ++ 2 files changed, 79 insertions(+), 22 deletions(-) diff --git a/snc.c b/snc.c index 58aea38..3585141 100644 --- a/snc.c +++ b/snc.c @@ -26,7 +26,12 @@ void usage() { - printf("Simple numbers converter\n" + printf("SNC (Simple numbers converter)\n" + "Copyright (C) 2021 Aleksandr D. Goncharov\n" + "SNC is free software; you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as\n" + "published by the Free SoftwareFoundation; either version\n" + "2 of the License, or (at your option) any later version.\n" "\n" "Synopsis: snc [OPTION] ... [NUMBER]\n" "Option:\n" @@ -37,14 +42,15 @@ void usage() "\t-o, --output\n" "\t\t****\n" "\t-a, --alphabet\n" - "\t\t****\n" + "\t\tOutput numeral system. Arabic is used by default\n" "\t-A, --list-alphabets\n" - "\t\t****\n"); + "\t\tPrint valid alphabets\n"); } int getRomanValue(char symbol) { - switch(symbol) { + switch(symbol) + { case 'I': return SNC_ROMAN_I; // have triple notation case 'V': return SNC_ROMAN_V; case 'X': return SNC_ROMAN_X; // have triple notation @@ -52,8 +58,8 @@ int getRomanValue(char symbol) case 'C': return SNC_ROMAN_C; // have triple notation case 'D': return SNC_ROMAN_D; case 'M': return SNC_ROMAN_M; // have triple notation + default: return 0; } - return 0; } int romanToArabic(char *str) @@ -66,8 +72,16 @@ int romanToArabic(char *str) int cur_value = getRomanValue(*str); if(cur_value == 0) return -1; - else if(last_value == cur_value || last_value == 0) { + + if(last_value == cur_value || last_value == 0) { + if(amount_char >= 3) + return -1; answer += cur_value; + if(cur_value == SNC_ROMAN_V || cur_value == SNC_ROMAN_L + || cur_value == SNC_ROMAN_D) { + if(amount_char > 1) return -1; + } + amount_char++; } else if(last_value > cur_value) { @@ -75,26 +89,19 @@ int romanToArabic(char *str) amount_char = 1; } else if(last_value < cur_value) { + if(amount_char > 1) + return -1; if(last_value * 10 < cur_value) return -1; - else if(last_value == SNC_ROMAN_V || - last_value == SNC_ROMAN_L || last_value == SNC_ROMAN_D) + if(last_value == SNC_ROMAN_V || last_value == SNC_ROMAN_L + || last_value == SNC_ROMAN_D) return -1; - + answer += cur_value - 2 * last_value; - if(amount_char > 1) - return -1; amount_char = 1; } last_value = cur_value; - if(amount_char > 3) - return -1; - else if(cur_value == SNC_ROMAN_V || - cur_value == SNC_ROMAN_L || cur_value == SNC_ROMAN_D) { - if(amount_char > 1) return -1; - } - str++; } @@ -138,10 +145,15 @@ int main(int argc, char *argv[]) {"input", required_argument, NULL, 'i'}, {"output", required_argument, NULL, 'o'}, {"alphabet", required_argument, NULL, 'a'}, - {"list-alphabets", required_argument, NULL, 'A'}, + {"list-alphabets", no_argument, NULL, 'A'}, {NULL, 0, NULL, 0} }; + int convert_from; + int convert_to = SNC_ARABIC; + //int input_base = 10; + //int output_base = 10; + while((result = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch(result) { @@ -156,14 +168,57 @@ int main(int argc, char *argv[]) break; } case 'a': { - break; + if(strcmp(optarg, "roman") == 0) { + convert_to = SNC_ROMAN; + break; + } + else if(strcmp(optarg, "arabic") == 0) { + convert_to = SNC_ARABIC; + break; + } + // else print all available alphabets } case 'A': { - break; + printf("Valid alphabets are: roman, arabic\n"); + return 0; } default: break; } } + char *str_number = argv[optind]; + if(!str_number) { + usage(); + return 1; + } + + if(atoi(argv[optind]) == 0) + convert_from = SNC_ROMAN; + else + convert_from = SNC_ARABIC; + + if(convert_to != convert_from) { + if(convert_to == SNC_ROMAN) { + char *answer = arabicToRoman(str_number); + if(!answer) { + printf("%s is not correct arabic number.\n", str_number); + return 1; + } + printf("%s\n", answer); + free(answer); + } + else { + int answer = romanToArabic(str_number); + if(answer == -1) { + printf("%s is not correct roman number.\n", str_number); + return 1; + } + printf("%d\n", answer); + } + } + else { + printf("%s\n", str_number); + } + return 0; -} \ No newline at end of file +} diff --git a/snc.h b/snc.h index 9b02b51..c7bd7c3 100644 --- a/snc.h +++ b/snc.h @@ -21,6 +21,8 @@ ***/ enum { + SNC_ARABIC, + SNC_ROMAN, SNC_ROMAN_I = 1, SNC_ROMAN_V = 5, SNC_ROMAN_X = 10, -- cgit v1.2.3-18-g5258