Reworked how flags are handled

This commit is contained in:
2019-03-07 11:33:22 -05:00
parent 8027293559
commit 2d6605127c

View File

@@ -35,6 +35,7 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <vector>
enum CipherFlagLocation { CAESAR, PLAYFAIR, VIGENERE, ATBASH, MORSE, AUTOKEY, NUM_CIPHERS, enum CipherFlagLocation { CAESAR, PLAYFAIR, VIGENERE, ATBASH, MORSE, AUTOKEY, NUM_CIPHERS,
@@ -43,10 +44,102 @@ std::string flagStrings[SIZE];
//Error handling //Error handling
bool failFlag = false; //Set if something fails bool failFlag = false; //Set if something fails
//For the getCipher function //Sets a typedef for the functions for the return
typedef std::string (*Fn)(std::ifstream&, bool); typedef std::string (*Fn)(std::ifstream&, bool);
/**
* @brief Set the array of strings that controls what each flag should look
*
*/
void setFlagStrings(){
flagStrings[CAESAR] = "c";
flagStrings[PLAYFAIR] = "p";
flagStrings[VIGENERE] = "v";
flagStrings[ATBASH] = "a";
flagStrings[MORSE] = "m";
flagStrings[AUTOKEY] = "u";
flagStrings[CipherFlagLocation::ENCODE] = "e";
flagStrings[CipherFlagLocation::DECODE] = "d";
flagStrings[INPUT_FILE] = "i";
flagStrings[OUTPUT_FILE] = "o";
}
/**
* @brief Takes the char** flags and turns them into a std::string to make it easier to process and sets the file names if necessary
*
* @param argc The number of arguments given
* @param argv The arguments given
* @param inputFileName The name of the input file if needed
* @param outputFileName The name of the output file if needed
*/
std::vector<std::string> flagsToStrings(int argc, char** argv, std::string& inputFileName, std::string& outputFileName){
std::vector<std::string> args;
bool getInputFile = false;
bool getOutputFile = false;
//Step through every element in argv adding it to the string (without the dashes)
for(int cnt = 1;cnt < argc;++cnt){
std::string tempArg = argv[cnt];
//If you find a dash add the next character to the
if(tempArg.at(0) == '-'){
//Step through every element in the rest of that string, adding all characters to the args string
for(unsigned long argCnt = 1;argCnt < tempArg.size();++argCnt){
args.push_back("");
args.at(args.size() - 1) = tempArg.at(argCnt);
//If one of the arguments is a file indicator set a flag to look for the file name
if(args.at(args.size() - 1) == flagStrings[INPUT_FILE]){
getInputFile = true;
}
else if(args.at(args.size() - 1) == flagStrings[OUTPUT_FILE]){
getOutputFile = true;
}
}
//Get the input file name if necessary
if(getInputFile){
++cnt;
if(cnt < argc){
inputFileName = argv[cnt];
}
else{
///Throw an error
}
}
//Get the output file name if necessary
if(getOutputFile){
++cnt;
if(cnt < argc){
outputFileName = argv[cnt];
}
else{
///Throw an error
}
}
}
else{
//Throw an error
}
}
//Return the vector of strings
return args;
}
/**
* @brief Takes an argument, searches the valid arguments that could be passed into the program, and sets the appropriate flags
*
* @param arg The argument that is currently being checked
* @param cipherFlags The array of booleans that act as flags that the rest of the program checks against
*/
void setArgs(std::string arg, bool cipherFlags[]){
//Check against every flag that can currently be set
for(int cnt = CipherFlagLocation::CAESAR;cnt < CipherFlagLocation::SIZE;++cnt){
//If the flag matches set the appropriate boolean and exit the function
if(arg == flagStrings[cnt]){
cipherFlags[cnt] = true;
return;
}
}
///Throw an error if the current flag was not found
}
/** /**
* @brief Takes all of the arguments that were given to the program and sets boolean flags inside the program that will change behavior * @brief Takes all of the arguments that were given to the program and sets boolean flags inside the program that will change behavior
@@ -57,37 +150,15 @@ typedef std::string (*Fn)(std::ifstream&, bool);
* @param inputFileString The name of the input file, if given * @param inputFileString The name of the input file, if given
* @param outputFileString The name of the output file if given * @param outputFileString The name of the output file if given
*/ */
void getFlags(int argc, char** argv, bool cipherFlags[], std::string& inputFileString, std::string& outputFileString){ void getFlags(int argc, char** argv, bool cipherFlags[], std::string& inputString, std::string& outputString){
//Cycle through every argument //Set the strings that control each
bool valid = false; setFlagStrings();
for(int cnt = 1;cnt < argc;++cnt){ //Turn the char** to string array
//Step through every element in the flagStrings and compare the flags. If the flags do not match or you go out of bounds in argv throw an error std::vector<std::string> args = flagsToStrings(argc, argv, inputString, outputString);
for(int stringcnt = 0;stringcnt < SIZE;++stringcnt){ //Cycle through every argument, checking it's validity and setting the correct flags
if(argv[cnt] == flagStrings[stringcnt]){ for(unsigned long argCnt = 0;argCnt < args.size();++argCnt){
valid = cipherFlags[stringcnt] = true; //Set all the arguments. If there is an invalid argument the function will throw an error
//If the flag showed an input file get the file name if possible setArgs(args.at(argCnt), cipherFlags);
if(stringcnt == INPUT_FILE){
//Make sure there is enough room in argv for the file name
if((cnt + 1) < argc){
inputFileString = argv[++cnt];
}
}
//If the flag showed an output file get the file name if possible
else if(stringcnt == OUTPUT_FILE){
//Make sure there is enough room in argv for the file name
if((cnt + 1) < argc){
outputFileString = argv[++cnt];
}
}
break;
}
}
//If the flag was not valid throw an error
if(!valid){
std::cout << argv[cnt] << " is an invalid flag" << std::endl;
return;
}
valid = false;
} }
} }
@@ -102,7 +173,7 @@ bool checkFlags(bool flags[]){
int counter = 0; int counter = 0;
bool correct = false; bool correct = false;
//Run through each flag and counter how many are true //Run through each flag and counter how many are true
for(int cnt = 0;cnt < NUM_CIPHERS;++cnt){ for(int cnt = CAESAR;cnt < NUM_CIPHERS;++cnt){
if(flags[cnt]){ if(flags[cnt]){
++counter; ++counter;
} }
@@ -114,30 +185,13 @@ bool checkFlags(bool flags[]){
} }
//Check if either encode or decode is set, but not both //Check if either encode or decode is set, but not both
if((flags[ENCODE] && flags[DECODE]) || (!flags[ENCODE] && !flags[DECODE])){ if((flags[CipherFlagLocation::ENCODE] && flags[CipherFlagLocation::DECODE]) || (!flags[CipherFlagLocation::ENCODE] && !flags[CipherFlagLocation::DECODE])){
correct = false; correct = false;
} }
return correct; return correct;
} }
/**
* @brief Set the array of strings that controls what each flag should look
*
*/
void setFlagStrings(){
flagStrings[CAESAR] = "-c";
flagStrings[PLAYFAIR] = "-p";
flagStrings[VIGENERE] = "-v";
flagStrings[ATBASH] = "-a";
flagStrings[MORSE] = "-m";
flagStrings[AUTOKEY] = "-u";
flagStrings[ENCODE] = "-e";
flagStrings[DECODE] = "-d";
flagStrings[INPUT_FILE] = "-i";
flagStrings[OUTPUT_FILE] = "-o";
}
/** /**
* @brief Run the appropriate commands to use a Caesar cipher * @brief Run the appropriate commands to use a Caesar cipher
* *