Reading Model Parameters from Files in C code

Learn about configuration files for models written in C

Introduction

C is great for doing calculations, simulations of the natural environment, parameter inversion and related tasks that are needed in geoscience applications. This code demonstrates the use of configuration files, which are often used in such applications.

Configuration files (sometimes called parameter files) are text files containing a list of parameters used in a code. When the code runs, the code reads the parameter file, just like a data file, but assigns variables in the code the values that are provided in the configuration file. The advantages of using configuration files are:

  • The configuration file preserves the values used when the code is run. This provides a record of your computational experiment. It is also very useful in environments where quality assurrance (QA) is required.
  • There is no need to re-compile the code when parameter values are changed. If parameters are defined within the code itself, every time they change the code must be re-compiled. This can be a hassle.
  • Configuration files can be created using other codes and other coding languages. Perhaps someone will use your C code for calculations, but create a configuration file using python or PERL, then run your C code with the new confiuguration file.
In short, configuration files are useful if you need to document your science and they can make your code easier to run, for you and for others.

[Top]

Reading parameters from a configuration file

Consider the following program, called data4.c.

Write this code in a text editor or copy the code into a text editor and name the file data4.c.

C code


/* data4.c
A program to read parameters from a seperate configuration
file and perform some calculation with the parameters. The parameters
in this example are crust density, gravity, and depth.
The code calculates the lithostatic pressure from these parameters.

Usage:
compile: gcc -o data4 data4.c
run: ./data4 config_filename

C. Connor
12/24/24

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Function to parse the configuration file and extract parameters
int parse_config(const char *filename, double *Crust_Density, double *Gravity, double *Depth) {
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        perror("Error opening config file");
        return -1;
    }

    char line[256];
    while (fgets(line, sizeof(line), file)) {
        if (line[0] == '#' || line[0] == '\n') {
            // Skip comment lines or empty lines
            continue;
        }

        char param[50];
        double value;
        if (sscanf(line, "%49s %lf", param, &value) == 2) {
            if (strcmp(param, "Crust_Density") == 0) {
                *Crust_Density = value;
            } else if (strcmp(param, "Gravity") == 0) {
                *Gravity = value;
            } else if (strcmp(param, "Depth") == 0) {
                *Depth = value;
            }
        }
    }

    fclose(file);
    return 0;
}

To use this code you will need a configuration. Create a configuration file called data4.conf using a text editor. The file should contain comments and parameters and their values. Save this file in the same directory as your code. Here are the data in the file used in this example:


# This is a configuration 
# file used by the code data4.c
# to demonstrate use of configuration files

#here is the parameter list
Crust_Density 2650 #crustal density (kg/m3)
Gravity 9.8 #gravitational acceleration (m/s2)
Depth 1.0e4 #Depth in meters

Note that the comment lines (hashtag) and the blank lines in the configuration file are ignored by the code. Also note that the parameter name is followed by the parameter value after a black space. Thsi is fairly standard syntax for configuration files.

[Top]

Compiling and running the code

To compile this C code, type on the command line:


gcc -o data4 data4.c -Wall

To run the code, type on the command line:


./data4 data4.conf

The output of the code is printed to the terminal window. Assuming your code compiled and ran with the proper data file name, your output on the command line is:


Parameters:
crustal density = 2650.00 kg/m3
gravity = 9.80 m/s2
depth = 10000.00 m

 Lithostatic pressure = (crust density * gravity * depth)/1e6 = 259.70 MPa

[Top]

Additional Explanation

As before (data1.c) the code using a Command-Line Input: The program expects the configuration file name as a command-line argument. If it's missing, the usage statement is printed.

A function is created outside main () to read the configuration file. This is good practice because reading the parameter values can be complicated and usually involves a lot of error checking and error handling. The variables (configuration file name, parameters) are listed as declared arguments for the function. They are listed as pointers to specific memory locations using the * symbol. The function changes the values stored in memory locations indicated by the pointers.

Notice the code handles as many comment and blank lines in the configuration file as needed. It searches for specific parameter names and their values using a conditional (if...then...else...else if) statement.

The main () function calls the function to read the parameters and performs the calculation.

Notice that the parameters are typed as "doubles" in the code regardless of how they are entered in the configuration file. That is, the parameter values are cast to the datatype demanded by the C code.

[Top]

Things to try

  • Copy the code into an editor, compile and run.
  • Change the configuration file and re-run the code. Introduce errors in the configuration file and see what the results look like. Add an additional parameter to the configuration file not needed by the code. For example: Crust_Viscosity 1e19 #Pa s. Does the code still run properly?
  • Modify the code to read a data file and a config file. For example, you could have a single column of depth values listed in a data file. Then the crustal density and gravity values could be gathered from the configuration file and lithostatic pressure calculated for each depth.
  • Code can be used to check for reasonable parameter ranges. For example, crustal density probably varies from 2000-3000 kg/m3. Try placing such a parameter check in your code and handling this error.