Main idea
Instead of using command parameters for your application you can setup a config file or even multiple config files.
This is the kind of code that is most useful in console application.
It allows to test or run your software in various ways.
In this manner you can configure strings, numbers and enable/disable flags to your application using a file you can edit in any text editor.
You can change the way your application behaves without recompiling it and it can be very helpful for testing purposes.
It is a very easy code to understand, and add configuration variables into.
The config file
For example use the following text in a file called configuration_1.cfg
The separator character in this example is the equal sign, but it can also be colon, tab or space.
# This is a comment # Configuration file number 1 MyFlag=Enabled MyString=config file is useful MyNumber=43
The coding part
First we should define the maximum length of lines we want to work with. I also like to to work with booleans as ints with values of 1 for true and 0 for false. so i will define the following.#define MAX_LINE_LENGTH 256 #define TRUE 1 #define FALSE 0A global configuration structure of type config_st can be used to store the parameters after they are parsed from the file. extend your application by adding additional variables that it needs to this structure.
typedef struct config_s
{
char configFileName[60];
int b_Flag;
int myNumber;
char myString[MAX_LINE_LENGTH];
}config_st;
To use this structure as a global variables add the following to your c file.
config_st g_config;
parsing the config file
The parseConfigFile function iterates over the config file line by line reading the parameters into a global config state.
On each line the first word is read into the param variable and the text after the separator character is read into the value variable. the if-else if logic that comes after that handles each variable according to it's type.
void parseConfigFile()
{
// parsing configuration file
char next_line[MAX_LINE_LENGTH];
char* value, *param;
int line = 0;
FILE * fd = fopen(g_config.configFileName, "r");
if (!fd) {
//could not open the file
return;
}
while (fgets(next_line, MAX_LINE_LENGTH, fd)) {
line++;
if ((next_line[0] == '#') || (next_line[0] == '\n')) {
// skip
} else {
//read from the line into param until the first separator
param = strtok(next_line," :=\t");
// continue tokenizing next_line until end of line is reached
value = strtok(NULL,"\n");
if ( (param == NULL) || (value == NULL) ) {
continue;
}
else if ( strcmp(param, "MyFlag") == 0 ) {
setTrueIfEnabled(value, &g_config.b_Flag);
}
else if ( strcmp(param, "MyString") == 0 ) {
strcpy(g_config.myString, value);
}
else if( strcmp(param, "MyNumber") == 0 ) {
g_config.myNumber = atoi(value);
}
}
}
//close the file
fclose(fd);
}
Helper functions
the setTrueIfEnabled helper function is used to set boolean flags
void setTrueIfEnabled(const char * key,int * result)
{
if (strcmp(key, "Enabled") == 0)
*result = TRUE;
else
*result = FALSE;
}
Required headers
Add the needed include files to your program.#include <string.h> #include <stdlib.h>
Main program example
Here is a simple main example that uses the config file parser, I hard code the file name here but it can be a command parameter if you use several configuration files.int main(int argc, char **argv)
{
sprintf(g_config.configFileName ,"%s", "configuration_1.cfg");
parseConfigFile();
printf("myNumber is %d\n",g_config.myNumber);
printf("myString is %s\n",g_config.myString);
printf("MyFlag is %d\n",g_config.b_Flag);
return 0;
}
Program output
myNumber is 43 myString is config file is useful MyFlag is 1
No comments:
Post a Comment