diff --git a/DIRECTORY.md b/DIRECTORY.md index 98526b9d..7f1268af 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -17,6 +17,7 @@ * [Decimal To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_octal.c) * [Decimal To Octal Recursion](https://github.com/TheAlgorithms/C/blob/master/conversions/decimal_to_octal_recursion.c) * [Hexadecimal To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal.c) + * [Hexadecimal To Octal2](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal2.c) * [Int To String](https://github.com/TheAlgorithms/C/blob/master/conversions/int_to_string.c) * [Octal To Binary](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_binary.c) * [Octal To Decimal](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_decimal.c) diff --git a/conversions/hexadecimal_to_octal2.c b/conversions/hexadecimal_to_octal2.c new file mode 100644 index 00000000..842e8e94 --- /dev/null +++ b/conversions/hexadecimal_to_octal2.c @@ -0,0 +1,119 @@ +/** + * @file + * @brief Convert hexadecimal number to octal number (with decimal intermediary) + * @details + * The input is valid from 0 to 0xFFFF_FFFF_FFFF_FFFF. + * + * At first, this program converts a hex string to an unsigned long long + * decimal, and then to an octal string. + * + * When there is an invalid character in input string, this program stops + * parsing and converts the string until that character. + * + * @see hexadecimal_to_octal.c + */ + +#include /// for printf() and fgets() +#include /// for memset() + +/** + * @brief Convert a hexadecimal number to octal number. + * @param hex Hexadecimal number to convert. + * @returns A pointer to the converted octal string. + */ +const char *hex_to_oct(const char *hex) +{ +#define MAX_OCT_STR_LEN 23 /* 17_7777_7777_7777_7777_7777 */ + static char octal[MAX_OCT_STR_LEN]; + memset(octal, '\0', MAX_OCT_STR_LEN); // Initialize as NULL string + + unsigned long long decimal = 0; + int i = 0; + int len; + + if (hex == NULL) + { + // Return an empty string + return octal; + } + + /* Hexadecimal to decimal conversion */ + while (*hex != '\n' && *hex != '\0') + { + char ch = *hex; + + if (ch >= '0' && ch <= '9') + { + ch -= '0'; + } + else if (ch >= 'a' && ch <= 'f') + { + ch = ch - 'a' + 10; + } + else if (ch >= 'A' && ch <= 'F') + { + ch = ch - 'A' + 10; + } + else + { + printf("Invalid hexadecimal input: %c\n", ch); + break; + } + + decimal *= 16; + decimal += ch; + hex++; + } + + /* Decimal to octal conversion */ + if (decimal == 0) + { + octal[0] = '0'; + len = 1; + } + else + { + i = 0; + while (decimal > 0) + { + octal[i] = '0' + decimal % 8; + i++; + decimal /= 8; + } + + len = i; + } + + octal[len] = '\0'; + + /* Reverse the octal string */ + for (i = 0; i < len / 2; i++) + { + char tmp = octal[i]; + octal[i] = octal[len - i - 1]; + octal[len - i - 1] = tmp; + } + + return octal; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() +{ +#define MAX_HEX_STR_LEN 17 /* FFFF_FFFF_FFFF_FFFF */ + char hex[MAX_HEX_STR_LEN]; + + /* Input hexadecimal number from user */ + printf("Enter any hexadecimal number: "); + fgets(hex, MAX_HEX_STR_LEN, stdin); + + const char *octal = hex_to_oct(hex); + + printf("Hexadecimal number = %s\n", hex); + printf("Octal number = %s\n", octal); + + return 0; +}