在C中读取名称/值对的最佳方法

时间:2019-03-29 00:47:42

标签: c linux string file

在C编程中从配置文件读取名称及其值的最佳方法是什么?

示例配置文件:

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

这是我正在使用的代码。这是工作。但我想知道是否有更好的方法。

#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;
}

我也很高兴听到此代码是否有任何问题。

1 个答案:

答案 0 :(得分:1)

有几个问题

  • 当文件如下所示时,您的解析不正确。只要line上有此字符串,就可以找到它,无论它是在键的值上还是键的一部分上。
NAMEX=xxxx
AGEX=44
DOB=mmddyyyyAGE
WORK=zzzzAGE
  • 使用strtok line的内容将被更改。实际上,当您第二次调用getValue时,line的内容与文件不同。
AGE=NAMEzzzz=1=2
  • 从性能上讲,您可以直接使用line子字符串,而无需删除

建议先解析键和值,然后多次比较您要查找的键。以下代码仅供参考

#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;
}