Created
April 14, 2020 05:40
-
-
Save faithandbrave/f6e0dcfd26575c6990f1b0aa7c06dec7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <getopt.h> | |
| #include <iostream> | |
| #include <bitset> | |
| #include <cstdint> | |
| #include <string> | |
| #include <string_view> | |
| #include <sstream> | |
| #include <optional> | |
| void print_help(std::ostream& os) { | |
| os << | |
| "usage baseconv:\n" | |
| " $ baseconv -i 10 -o 16 32\n" | |
| " 20\n" | |
| "\n" | |
| " $ baseconv -o 16 32\n" | |
| " 20\n" | |
| << std::endl; | |
| } | |
| std::int64_t parse_value(std::string_view svalue, std::optional<int> from_base) { | |
| if (!from_base) { | |
| if (svalue.starts_with("0b")) { | |
| svalue.remove_prefix(2); | |
| return std::bitset<64>(std::string{svalue}).to_ullong(); | |
| } | |
| return std::stoll(std::string{svalue}, nullptr, 0); | |
| } | |
| int base = from_base.value(); | |
| if (base == 2) { | |
| if (svalue.starts_with("0b")) { | |
| svalue.remove_prefix(2); | |
| } | |
| return std::bitset<64>(std::string{svalue}).to_ullong(); | |
| } | |
| else if (base == 16 || base == 10) { | |
| return std::stoll(std::string{svalue}, nullptr, 0); | |
| } | |
| else { | |
| throw std::invalid_argument("invalid base"); | |
| } | |
| } | |
| std::string generate_value(std::int64_t value, int base) { | |
| if (base == 2) { | |
| return std::bitset<64>(value).to_string(); | |
| } | |
| else if (base == 16) { | |
| std::stringstream ss; | |
| ss << std::hex << value; | |
| return ss.str(); | |
| } | |
| else if (base == 10) { | |
| return std::to_string(value); | |
| } | |
| else { | |
| throw std::invalid_argument("invalid base"); | |
| } | |
| } | |
| int main(int argc, char* argv[]) | |
| { | |
| std::optional<int> from_base; | |
| std::optional<int> to_base; | |
| int opt; | |
| while ((opt = getopt(argc, argv, "i:o:h:?:")) != EOF) { | |
| switch (opt) { | |
| case 'i': | |
| from_base = std::atoi(optarg); | |
| break; | |
| case 'o': | |
| to_base = std::atoi(optarg); | |
| break; | |
| case 'h': | |
| print_help(std::cout); | |
| return 0; | |
| case '?': | |
| print_help(std::cerr); | |
| return 1; | |
| } | |
| } | |
| if (!to_base) { | |
| std::cerr << "you should specify output base. e.g. `-o 16`" << std::endl; | |
| return 1; | |
| } | |
| std::string svalue; | |
| svalue = argv[optind++]; | |
| if (svalue.empty()) { | |
| std::cerr << "you should specify value" << std::endl; | |
| return 1; | |
| } | |
| std::int64_t value = 0; | |
| try { | |
| value = parse_value(svalue, from_base); | |
| } | |
| catch (std::exception& e) { | |
| std::cerr << e.what() << std::endl; | |
| return 1; | |
| } | |
| try { | |
| std::string output = generate_value(value, to_base.value()); | |
| std::cout << output << std::endl; | |
| } | |
| catch (std::exception& e) { | |
| std::cout << e.what() << std::endl; | |
| return 1; | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
requires C++20 (
basic_string_view::starts_with()).build :
usage :