Reputation: 586
I have a cpp code which uses configuration variables from a header file to do some calculations. The structure of my program is as follows
#include configuration_variables.h
#include <necessary headers>
void main(){
<code>
}
configuration_variables.h
const int start = 5;
const int end = 10;
int detectors[6] = {2, 3, 4, 6, 7, 8};
string filters[2] = {"Cd", "Pb"};
<more variables>
<and more variables>
The configuration variables and the name of the header file are expected to change when trying to solve the same problem with different input (i.e. configuration variables) which means I have to recompile the code.
Is there a way to read a different configuration file each time it;s needed and parse the variables in the main code? I think it might be more elegant than what I'm currently doing but the configuration variables are not just scalars, so text processing them (i.e. with awk) might not be that easy.
Upvotes: 0
Views: 1965
Reputation: 124
You can pass input to your program in two ways: using command-line parameters, or in a file. Looking at the number of variables you have, it is probably better if you store your values in a file, then pass the file through command-line args. It sounds like you want to pass in the header file itself. You can still make that work but parsing the C/C++ syntax is not preferable. It will probably be better to save your parameters in a different format (like JSON, CSV, or even your own).
Depending on how complex your program can get, there are a lot of things you can do. But if you want to keep everything simple, make the config file a positional argument to the program, then parse it according to whatever format you decide for your program. Here's an example:
#include <fstream>
#include <string>
struct config{
int start;
int end;
int detectors[6];
std::string filters[2];
};
struct config parse_file(char * file_name){
std::ifstream file;
file.open(file_name, std::ifstream::in);
// now parse the file using >> operators
// if you aren't guaranteed to get a properly formatted file
// you should check for incorrect format here and handle appropriately
struct config param;
file >> param.start;
file >> param.end;
for(int i = 0 ; i < 5 ; i++){
file >> param.detectors[i];
}
file >> param.filters[0];
file >> param.filters[1];
return param;
}
int main(int argc, char **argv){
if(argc < 2 || argc >= 3){
// deal with no input/more than expected input
exit(0);
}
struct config params = parse_file(argv[1]); // argv[0] stores binary name
//use params as needed
}
You can make this more complex as needed for your usecase. For example, you can use boost's program options library or the c standard getopt library to pass this config file, and additional arguments for your program like standard unix tools. There are also libraries that parse standard file formats (like CSV, JSON, XML). Examples that I found with a quick search: RapidJSON, Lightweight XML parser
If you absolutely want to stick to using header files, I found this c++ library that parses c++ headers and formats them into json. It is probably an overkill since it can also parse classes and templates. You will need to modify it to integrate it with your code.
Upvotes: 1
Reputation: 3382
I don't see an issue with what your doing, apart from some redefinition errors. Mark those variables as inline
or else they will get redefined multiple times, thus it might cause you some errors. If they are meant to be constants, mark them as const
or constexpr
.
Is there a way to read a configuration file and parse the variables in the main code?
If I understood it correctly, yes you can use a file to initialize them. Store the variables in a .config
or .txt
file and later parse it and initialize the variables with data. I'm not sure if its with a lot of benefits as you'll spend some performance loading the file and initializing the values. If you predefined it in the header, then the compiler will take care of it.
Upvotes: 1