Gnuに勝てるわけないだろ!馬鹿野郎お前俺は書くぞお前!
というわけでC++でコマンドライン引数をparseしたいわけで、
gccにはgnu getoptという素敵な物があるわけですが、
Gnu汚染やだよねとかいうアレコレもあるので、書いてみました。
#pragma once
#include <string>
#include <iostream>
#include <vector>
#include <map>
class Option{
std::map<const std::string, const bool> shortNoArg;
std::map<const std::string, const std::string> shortWithArg;
void Parse(const std::size_t argc, const std::string* const options){
for(std::size_t i = 0 ; i < argc ; ++ i){
if(options[i][0] == '-'){
//This is opt
//If this is the last, this is bool.
if(i == argc - 1){
for(std::size_t c = 1 ; c < options[i].length() ; ++ c){
shortNoArg.insert(std::map<std::string, bool>::value_type(options[i].substr(c, 1), true));
}
}else{
//Look up next and if it starts '-', this is bool.
if(options[i+1][0] == '-'){
for(std::size_t c = 1 ; c < options[i].length() ; ++ c){
shortNoArg.insert(std::map<std::string, bool>::value_type(options[i].substr(c, 1), true));
}
}else{//otherwise
shortWithArg.insert(std::map<std::string, std::string>::value_type(options[i].substr(1, 1), options[i+1]));
}
}
}else{
//This is arg
}
}
}
public:
Option(std::size_t argc, char** argv){
std::string* options = new std::string[argc];
for(std::size_t i = 0 ; i < argc ; ++ i){
options[i] = argv[i];
}
Parse(argc, options);
delete [] options;
}
~Option(){
}
void Show(void){
std::cout << "Boolean Options" << std::endl;
for(std::map<const std::string, const bool>::iterator it = shortNoArg.begin() ; it != shortNoArg.end() ; ++ it){
std::cout << it->first << ", " << it->second << std::endl;
}
std::cout << "Options w/ Argument" << std::endl;
for(std::map<const std::string, const std::string>::iterator it = shortWithArg.begin() ; it != shortWithArg.end() ; ++ it){
std::cout << it->first << ", " << it->second << std::endl;
}
}
bool GetShortNoArgument(const std::string key){
return shortNoArg[key];
}
std::string GetShortWithArgument(const std::string key){
return shortWithArg[key];
}
};
で、これをopt.hみたいな名前にしといて、
つかい方としてはこんな感じ。
#include "opt.h"
int main(int argc, char** argv){
Option opts(argc, argv);
opts.Show();
std::cout << opts.GetShortNoArgument("a") << std::endl;
std::cout << opts.GetShortWithArgument("b") << std::endl;
return 0;
}
で、コンパイルして./a.out -a -b test
とか打つと、
aはbooleanでtrueに、bにtestが帰ってくる。
おすぃまい。
--versionみたいなlongな形式にはそのうち対応する…かも。