Skip to content

Instantly share code, notes, and snippets.

@faithandbrave
Created April 14, 2020 05:40
Show Gist options
  • Select an option

  • Save faithandbrave/f6e0dcfd26575c6990f1b0aa7c06dec7 to your computer and use it in GitHub Desktop.

Select an option

Save faithandbrave/f6e0dcfd26575c6990f1b0aa7c06dec7 to your computer and use it in GitHub Desktop.
#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;
}
}
@faithandbrave

faithandbrave commented Apr 14, 2020 •

Copy link
Copy Markdown
Author

requires C++20 (basic_string_view::starts_with()).

build :

$ g++ baseconv.cpp -std=c++2a -o baseconv

usage :

$ baseconv -i 10 -o 16 32
20
 
$ baseconv -o 16 32
20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment