0

What is the best way to read name and its value from a configuration file in c programming?

Sample configuration file:

NAME=xxxx
AGE=44
DOB=mmddyyyy
WORK=zzzz

This is the code which I am using. It is working. But I would like to know if there is a better way.

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

int getValue(char *line, char* name, char value[])
{
    char* pch = NULL;
    char* token = NULL;
    pch = strstr(line, name);

    if(pch)
    {
        token = strtok(pch, "=");

        while (token != NULL)
        {
            pch = token;
            token = strtok(NULL, "=");
        }
        pch[strcspn ( pch, "\n" )] = '\0';
        strcpy(value,pch);
        return 1;
    }
    return 0;
}

int main()
{
    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;
    char value[100];
    int ret = 0;

    fp = fopen("test.txt", "r");
    if (fp == NULL)
    {
        printf ("Cannot open file \n");
        return -1;
    }

    while ((read = getline(&line, &len, fp)) != -1)
    {
        ret = getValue(line,"NAME",value);
        if (ret)
        {
            printf("NAME is %s\n", value);
        }

        ret = getValue(line,"AGE",value);
        if (ret)
        {
            printf("AGE is %s\n", value);
        }
    }

    free(line);
    fclose(fp);
    return 0;
}

I would be also happy to hear if there is any issue with this code.

A R
  • 2,697
  • 3
  • 21
  • 38
  • you can start changing `strtok` by `strsep` due to it's a deprecated function more information [here](https://stackoverflow.com/questions/44336831/why-should-strtok-be-deprecated), simple example using `strsep` [here](https://stackoverflow.com/questions/55402578/parse-string-to-multiple-vars/55404540#55404540) – Miguel Ángel Retamozo Sanchez Mar 29 '19 at 00:52
  • The *best* way would be to use a library explicitly built to handle such things. – Scott Hunter Mar 29 '19 at 00:53
  • [Read name value pairs from a file in C](https://stackoverflow.com/q/13390133/608639) – jww Mar 29 '19 at 08:25

1 Answers1

1

There are several issues

  • When the file is like below, your parsing is incorrect. it be found as long as there is this string on the line, regardless of whether it is on the value or part of the key.
NAMEX=xxxx
AGEX=44
DOB=mmddyyyyAGE
WORK=zzzzAGE
  • Use strtok line content will be changed. In fact, when you call getValue for the second time, the content of line is different from the file.
AGE=NAMEzzzz=1=2
  • From the performance, you can directly use line the substring, no need to strcpy out

It is recommended to parse the key and value first, then compare the key you are looking for multiple times. the code below is for reference only

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

char *trim(char *str)
{
    char *start = str;
    char *end = str + strlen(str);

    while(*start && isspace(*start))
        start++;

    while(end > start && isspace(*(end - 1)))
        end--;

    *end = '\0';
    return start;
}

int parse_line(char *line, char **key, char **value)
{
    char *ptr = strchr(line, '=');
    if (ptr == NULL)
        return -1;

    *ptr++ = '\0';
    *key = trim(line);
    *value = trim(ptr);

    return 0;
}

int main()
{
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    char *key, *value;

    fp = fopen("test.txt", "r");
    if (fp == NULL) {
        printf ("Cannot open file \n");
        return -1;
    }

    while ((read = getline(&line, &len, fp)) != -1) {
        if (parse_line(line, &key, &value))
            continue;

        if (strcmp(key, "NAME") == 0) {
            printf("NAME is %s\n", value);
        } else if (strcmp(key, "AGE") == 0) {
            printf("AGE is %s\n", value);
        }
    }

    free(line);
    fclose(fp);

    return 0;
}
ccxxshow
  • 844
  • 6
  • 5