Last active
October 14, 2022 06:38
-
-
Save xaliphostes/58eae0a04a38c6f11476702865b139ab to your computer and use it in GitHub Desktop.
https://repl.it/CYSv/30 created by xaliphostes
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
/** | |
* ------------------------------------------------------------ | |
* Show how convenient it is to use classes instead of a bunch | |
* of C functions. | |
* | |
* Part of the OOP course for PhD students and Researchers. | |
* | |
* Contact: [email protected] | |
* ------------------------------------------------------------ | |
*/ | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <algorithm> | |
using namespace std ; | |
/** | |
* @brief A convenient class which help to analyse arguments passed to a command-line. | |
* An argument starts with a minus (a switch), the next argument is either its | |
* value or a next switch. | |
* @note We didn't put any comment in the class as it is self explanatory. | |
* @note Public are first since this is what we are interested in (client code). | |
* Private methods and members follow as they are useless for us. | |
* @note Note how public methods are indented for a better reading of the return | |
* type and the arguments. | |
* @note It is better to write the implementation elsewhere, even if it requires more | |
* writting...That way, the class interface is more simple, less overloaded and | |
* more clear. | |
*/ | |
class Args { | |
public: | |
Args(const string& argv) ; | |
bool exists (const string& name) const ; | |
bool hasValue(const string& name) const ; | |
string value (const string& name) const ; | |
vector<string> switches() const ; | |
void display () const ; | |
private: | |
vector<string> split(const string& str, int delimiter(int) = ::isspace) ; | |
int index(const string& name) const ; | |
string argv_ ; | |
vector<string> toks_ ; | |
} ; | |
// ----------------------------------------------------------------------------------- | |
// A convenient function for testing | |
// | |
void check(const Args& a, const string& name) { | |
if (a.exists(name)) { | |
cerr << "switch '" << name << "' exists with value " << a.value(name) << endl ; | |
} else { | |
cerr << "switch '" << name << "' does not exist!" << endl ; | |
} | |
} | |
// ----------------------------------------------------------------------------------- | |
int main(int argc, char** argv) { | |
Args a("-aux 23 -u toto -tol 1e-8 -c -o aaa -name \"filename.txt\" -j") ; | |
cerr << "---------------------------------" << endl ; | |
check(a, "tol") ; | |
cerr << "---------------------------------" << endl ; | |
check(a, "epsilon") ; | |
cerr << "---------------------------------" << endl ; | |
vector<string> switches = a.switches() ; | |
cerr << "List of switches:" << endl ; | |
for (const string& s : switches) { | |
if (a.hasValue(s)) | |
cerr << " [" << s << "] has value [" << a.value(s) << "]" << endl ; | |
else | |
cerr << " [" << s << "]" << endl ; | |
} | |
cerr << "---------------------------------" << endl ; | |
} | |
// ================== IMPL ================================================== | |
Args::Args(const string& argv): argv_(argv) { | |
toks_ = split(argv) ; | |
} | |
bool Args::exists(const string& name) const { | |
return index(name) !=-1 ; | |
} | |
string Args::value(const string& name) const { | |
int i = index(name) ; | |
if (i==-1) { | |
return "" ; | |
} | |
if (i>=toks_.size()-1) { | |
return "" ; | |
} | |
return toks_[i+1] ; | |
} | |
bool Args::hasValue(const string& name) const { | |
int i = index(name) ; | |
if (i==-1) { | |
return false ; | |
} | |
if (i>=toks_.size()-1) { | |
return false ; | |
} | |
if (toks_[i+1][0]=='-') { | |
return false ; | |
} | |
return true ; | |
} | |
vector<string> Args::switches() const { | |
vector<string> s ; | |
for (int i=0; i<toks_.size(); ++i) { | |
if (toks_[i][0]=='-') { | |
s.push_back(toks_[i].substr(1,string::npos)) ; | |
} | |
} | |
return s ; | |
} | |
void Args::display () const { | |
for (int i=0; i<toks_.size(); ++i) { | |
if (toks_[i][0]=='-') { | |
cerr << toks_[i].substr(1,string::npos) ; | |
if (i<toks_.size()-1 && toks_[i+1][0]!='-') { | |
cerr << "\t" << toks_[i+1] ; | |
i++ ; | |
} | |
cerr << endl ; | |
} | |
} | |
} | |
// private | |
vector<string> Args::split(const string& str, int delimiter(int)) { | |
vector<string> result ; | |
auto e=str.end() ; | |
auto i=str.begin() ; | |
while(i!=e) { | |
i = find_if_not(i,e, delimiter) ; | |
if (i==e) { | |
break ; | |
} | |
auto j = find_if(i,e, delimiter) ; | |
result.push_back(string(i,j)) ; | |
i = j ; | |
} | |
return result ; | |
} | |
int Args::index(const string& name) const { | |
for (int i=0; i<toks_.size(); ++i) { | |
if (toks_[i][0]=='-') { | |
if (toks_[i].substr(1,string::npos)==name) { | |
return i ; | |
} | |
} | |
} | |
return -1 ; | |
} |
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
gcc version 4.6.3 | |
Command launched: | |
args -aux 23 -u toto -tol 1e-8 -c -o aaa -name "filename.txt" -j | |
>>> --------------------------------- | |
switch 'tol' exists with value 1e-8 | |
--------------------------------- | |
switch 'epsilon' does not exist! | |
--------------------------------- | |
List of switches: | |
[aux] has value [23] | |
[u] has value [toto] | |
[tol] has value [1e-8] | |
[c] | |
[o] has value [aaa] | |
[name] has value ["filename.txt"] | |
[j] | |
--------------------------------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment