diff --git a/ch_02/hex_converter/main.c b/ch_02/hex_converter/main.c new file mode 100644 index 0000000..28c97c7 --- /dev/null +++ b/ch_02/hex_converter/main.c @@ -0,0 +1,344 @@ +/* + * + * Write a program that can convert a decimal to a hex value and vice-versa. + * The program must pass a command line argument to determine what will + * be the conversion type and the value to be converted. The value + * must be evaluated to make sure it's valid before converting. + * Otherwise, inform the user and terminate the program + * + * Author: Kun Deng + */ + + + +#include +#include + +// Symbolic constants +#define INVALID 0 +#define HEX 1 +#define NUMBER 2 + + +char hex_value[15]; + +// Return values +// 0 - Invalid +// 1 - Converting to hex +// 2 - Converting to number +int is_valid_conversion_target(char *target); + +// Parameter target_type is the valid target type +// Should match the symbolic constants of HEX or NUMBER +// +// Return values +// 0 - Invalid +// 1 - Valid +int is_valid_source(char *value, int target_type); + +// Returns the size of the string. Assumes that the value is a null terminated string +int size_of_string(char *value); + +// Compares two strings. Assumes that the strings are null terminated +// Return values +// 0 - Not equal +// 1 - Equal +int compare_string(char *first, char *second); + +// Converts the hex value to a number +int hex_conveted_to_number(char *value); + + +// Converts the number to a hex value +char* number_converted_to_hex(char *value); + + +// Converts a digit to it's Hex counterpart. +// Ex. 15 would be F +char convert_hex_part(int val); + + +// Reverses the order of a null terminated string +void reverse_order(char *val); + + +int main(int argc, char **argv) +{ + if (argc < 3) + { + printf("Provide two arguments:\n"); + printf("./program [conversion_target] [decimal | hex value]\n"); + printf("[conversion_target] - hex or dec as the target\n"); + printf("hex - converts the decimal value to hex\n"); + printf("dec - converts the hex value to decimal\n"); + + return -1; + } + + char *conversion_target = *(argv + 1); + + printf("Chose conversion target %s\n", conversion_target); + + int valid_target = is_valid_conversion_target(conversion_target); + char *val = *(argv + 2); + + switch (valid_target) + { + case HEX: + printf("%s is a valid conversion target\n", conversion_target); + + if (is_valid_source(val, HEX) != 1) + { + printf("%s is not a valid number\n", val); + + return -1; + } + + char *converted_to_hex = number_converted_to_hex(val); + + printf("%s converted to hex is %s\n", val, converted_to_hex); + break; + case NUMBER: + printf("%s is a valid conversion target\n", conversion_target); + + if (is_valid_source(val, NUMBER) != 1) + { + printf("%s is not a valid hex number\n", val); + } + break; + case INVALID: + printf("%s is an invalid conversion target\n", conversion_target); + break; + default: + break; + } + + + return 0; +} + + + +int is_valid_conversion_target(char *target) +{ + int result = 0; + + if (compare_string(target, "hex") == 1) + { + result = 1; + } + else if (compare_string(target, "num") == 1) + { + result = 2; + } + + + return result; +} + +int is_valid_source(char *value, int target_type) +{ + int result = 1; + + for (int i = 0; value[i] != '\0'; ++i) + { + char val = value[i]; + + if (target_type == NUMBER) + { + // ASCI values + // 48 - 57 are numbers + // 65 - 70 are upper case letters (A-F) + // 97 - 102 are lower case letters (a-f) + if (!(val >= 48 && val <= 57) && + !(val >= 65 && val <= 70) && + !(val >= 97 && val <= 102)) + { + result = 0; + break; + } + } + else if (target_type == HEX) + { + // ASCII values 48 - 57 are numbers + // Checks to see if there are non-numbers + if (val <= 47 || val >= 58) + { + result = 0; + break; + } + } + } + + return result; +} + +int size_of_string(char *value) +{ + int size = 0; + + while (value[size] != '\0') + { + ++size; + } + + return size; +} + +int compare_string(char *first, char *second) +{ + int result = 1; + int size_first, size_second; + + size_first = size_of_string(first); + size_second = size_of_string(second); + + if (size_first != size_second) + { + return --result; + } + + for (int i = 0; i != size_first; ++i) + { + if (first[i] != second[i]) + { + result = 0; + break; + } + } + + + return result; +} + +int hex_conveted_to_number(char *value) +{ + int number = 0; + + return number; +} + + +char *number_converted_to_hex(char *value) +{ + int number_value = atoi(value); + int string_size = size_of_string(value); + + extern char hex_value[]; + + int hex_start = 0; + + for (double number = number_value;;) + { + double quotient = number / 16.0; + int quotient_trunecated = number / 16; + double remaining = quotient - quotient_trunecated; + int number_hex_part = remaining * 16; + + if (number >= 16) + { + char hex_part = convert_hex_part(number_hex_part); + printf("Hex part %c\n", hex_part); + + hex_value[hex_start++] = hex_part; + } + else + { + char hex_part = convert_hex_part(number_hex_part); + printf("Last Hex part %c\n", hex_part); + + hex_value[hex_start++] = hex_part; + break; + } + + number = quotient_trunecated; + } + + hex_value[hex_start] = '\0'; + + if (hex_start > 1) + { + reverse_order(hex_value); + } + + /** + for (int i = (string_size - 1); i >= 0; --i) + { + int number_part = value[i] - '0'; + + printf("Number part %d\n", number_part); + + + ++hex_start; + } + */ + + + return hex_value; +} + + +char convert_hex_part(int val) +{ + char result; + + if (val == 15) + { + result = 'F'; + } + else if (val == 14) + { + result = 'E'; + } + else if (val == 13) + { + result = 'D'; + } + else if (val == 12) + { + result = 'C'; + } + else if (val == 11) + { + result = 'B'; + } + else if (val == 10) + { + result = 'A'; + } + else + { + result = val + '0'; + } + + return result; +} + + +void reverse_order(char *value) +{ + int string_size = size_of_string(value); + + printf("Before %s", value); + + for (int i = 0;; ++i) + { + char tmp = value[string_size - i - 1]; + value[string_size - i - 1] = value[i]; + value[i] = tmp; + + // 1 if odd, 0 if true + int is_odd = string_size % 2; + + if (is_odd == 1 && (string_size / 2) == ((i + 1))) + { + break; + } + else if (is_odd == 0 && (string_size / 2) == (i + 1)) + { + break; + } + } + + printf(" After %s\n", value); +} diff --git a/ch_02/hex_converter/main_template.c b/ch_02/hex_converter/main_template.c deleted file mode 100644 index d432873..0000000 --- a/ch_02/hex_converter/main_template.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * - * Write a program that can convert a decimal to a hex value and vice-versa. - * The program must pass a command line argument to determine what will - * be the conversion type and the value to be converted. The value - * must be evaluated to make sure it's valid before converting. - * Otherwise, inform the user and terminate the program - * - * Author: Kun Deng - */ diff --git a/ch_02/octal_converter/README.md b/ch_02/octal_converter/README.md new file mode 100644 index 0000000..15f93da --- /dev/null +++ b/ch_02/octal_converter/README.md @@ -0,0 +1,2 @@ +compile with math library using gcc: +gcc main.c -lm diff --git a/ch_02/octal_converter/main.c b/ch_02/octal_converter/main.c index 3883041..332d8a5 100644 --- a/ch_02/octal_converter/main.c +++ b/ch_02/octal_converter/main.c @@ -1,6 +1,6 @@ /* * - * Write a program that can convert a decimal to a hex value and vice-versa. + * Write a program that can convert a number to a hex value and vice-versa. * The program must pass a command line argument to determine what will * be the conversion type and the value to be converted. The value * must be evaluated to make sure it's valid before converting. @@ -14,16 +14,16 @@ #include #define OCTAL 1 -#define DECIMAL 2 +#define NUMBER 2 // Returns 1 if octal conversion was chosen -// Returns 2 if decimal conversion was chosen +// Returns 2 if number conversion was chosen // Returns 0 or non-zero number if not valid -int valid_conversion_option(char *option); +int valid_conversion_target(char *target); -// Returns 1 if valid and 0 if the decimal value isn't -int valid_decimal_value(char *value); +// Returns 1 if valid and 0 if the number value isn't +int valid_number_value(char *value); // Returns 1 if valid and 0 if the octal value isn't int valid_octal_value(char *value); @@ -33,41 +33,45 @@ int valid_octal_value(char *value); int size_of_value(char *value); -// Converts decimal value to octal and prints the value +// Converts number value to octal and prints the value void convert_to_octal(char *value); -// Converts octal value to decimal and prints the value -void convert_to_decimal(char *value); +// Converts octal value to number and prints the value +void convert_to_number(char *value); int main(int argc, char **argv) { if (argc < 3) { - printf("Provide two arguments: ./program [conversion_option] [decimal | octal value]\n"); + printf("Provide two arguments:\n"); + printf("./program [conversion_target] [number | octal value]\n"); + printf("[conversion_target] - oct or num as the target\n"); + printf("oct - Converts the number to a hex value\n"); + printf("num - Converts the octal value to a number\n"); return -1; } - char *conversion_option = argv[1]; - int result = valid_conversion_option(conversion_option); + char *conversion_target = argv[1]; + int result = valid_conversion_target(conversion_target); if (result < 1) { - printf("Invalid conversion option %s.\noct and dec are only supported\n", conversion_option); + printf("Invalid conversion target %s.\noct and num are only supported\n", conversion_target); return -1; } - printf("%s is a valid conversion option\n", conversion_option); + printf("%s is a valid conversion target\n", conversion_target); switch (result) { case OCTAL: - if (valid_decimal_value(argv[2]) == 0) + if (valid_number_value(argv[2]) == 0) { - printf ("Invalid decimal value %s\n", argv[2]); + printf ("Invalid number value %s\n", argv[2]); return -1; } @@ -75,7 +79,7 @@ int main(int argc, char **argv) convert_to_octal(argv[2]); break; - case DECIMAL: + case NUMBER: if (valid_octal_value(argv[2]) == 0) { printf("Invalid octal value %s\n", argv[2]); @@ -83,7 +87,7 @@ int main(int argc, char **argv) return -1; } - convert_to_decimal(argv[2]); + convert_to_number(argv[2]); break; } @@ -93,12 +97,12 @@ int main(int argc, char **argv) } -int valid_conversion_option(char *option) +int valid_conversion_target(char *target) { const int OPTION_SIZE = 4; - // Supported conversion options + // Supported conversion targets char *oct = "oct"; - char *dec = "dec"; + char *num = "num"; int result = 0; @@ -106,7 +110,7 @@ int valid_conversion_option(char *option) for (int a = 0; a != OPTION_SIZE; ++a) { // Checking to see if octal conversion is selected - if (option[a] != oct[a]) + if (target[a] != oct[a]) { break; } @@ -119,8 +123,8 @@ int valid_conversion_option(char *option) for (int a = 0; a != OPTION_SIZE; ++a) { - // Checking to see if decimal conversion is selected - if (option[a] != dec[a]) + // Checking to see if number conversion is selected + if (target[a] != num[a]) { break; } @@ -135,7 +139,7 @@ int valid_conversion_option(char *option) return result; } -int valid_decimal_value(char *value) +int valid_number_value(char *value) { int result = 1; @@ -143,11 +147,11 @@ int valid_decimal_value(char *value) { // ASCII value 48 is 0. ASCII value 57 is 9. // If value contains any non-numbers then - // the value isn't a valid decimal value + // the value isn't a valid number value if (value[a] < 48 || value[a] > 57) { result = 0; - printf("Invalid character for decimal %c\n", value[a]); + printf("Invalid character for number %c\n", value[a]); break; } @@ -190,31 +194,31 @@ int size_of_value(char *value) void convert_to_octal(char *value) { - int value_decimal = atoi(value); + int value_number = atoi(value); char octal_value[12] = "00000000000\0"; int index = 0; - printf("Converting %d to octal\n", value_decimal); + printf("Converting %d to octal\n", value_number); - for (double quotient_decimal = value_decimal; (quotient_decimal >= 0);) + for (double quotient_number = value_number; (quotient_number >= 0);) { - if (quotient_decimal == 0) + if (quotient_number == 0) { octal_value[index] = '0'; break; } else { - quotient_decimal /= 8; - int trunecated_quotient_decimal = quotient_decimal; - double remaining = quotient_decimal - trunecated_quotient_decimal; + quotient_number /= 8; + int trunecated_quotient_number = quotient_number; + double remaining = quotient_number - trunecated_quotient_number; int octal_part = remaining * 8; - printf("Octal part %d index %d remaining %f\n", octal_part, index, quotient_decimal); + printf("Octal part %d index %d remaining %f\n", octal_part, index, quotient_number); octal_value[index] = octal_part + '0'; - quotient_decimal = trunecated_quotient_decimal; + quotient_number = trunecated_quotient_number; ++index; } @@ -231,24 +235,24 @@ void convert_to_octal(char *value) } - printf("Decimal value %d is %s in octal\n", value_decimal, octal_value); + printf("Decimal value %d is %s in octal\n", value_number, octal_value); } -void convert_to_decimal(char *value) +void convert_to_number(char *value) { - int octal_converted_to_decimal = 0; + int octal_converted_to_number = 0; int power_value = 0; - printf("Converting %s to decimal\n", value); + printf("Converting %s to number\n", value); for (int a = size_of_value(value) - 1; a >= 0; --a) { int octal_part = value[a] - '0'; int octal_power = octal_part * pow(8, power_value++); - octal_converted_to_decimal += octal_power; + octal_converted_to_number += octal_power; printf("Octal part %d octal power %d\n", octal_part, octal_power); } - printf("Octal value %s is %d in decimal\n", value, octal_converted_to_decimal); + printf("Octal value %s is %d in number\n", value, octal_converted_to_number); } diff --git a/ch_02/octal_converter/main_template.c b/ch_02/octal_converter/main_template.c deleted file mode 100644 index d432873..0000000 --- a/ch_02/octal_converter/main_template.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * - * Write a program that can convert a decimal to a hex value and vice-versa. - * The program must pass a command line argument to determine what will - * be the conversion type and the value to be converted. The value - * must be evaluated to make sure it's valid before converting. - * Otherwise, inform the user and terminate the program - * - * Author: Kun Deng - */