在 C 中通过引用传递结构,但修改并非全部存在

Pass struct by reference in C, but modifications aren't all there

我正在尝试编写一个简单的程序来读取 C 中的配置文件。但是我的结构成员中的数据并没有保留在我放置的位置。

代码在底部。

这就是我认为我正在做的事情:

当我尝试访问成员时,我只能从配置文件的最后一行获取数据。

谢谢!


编辑:我希望它使用配置文件中的键/值填充结构。相反,它只有配置文件中最后一行的值。

预期输出

example.com

实际产量

food.txt

问题在于:

conf->key[i]   = key;
conf->value[i] = value;

main.c

/*
* Goal is to make simple key value storage with struct and pointers
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLEN 100
#define CONFIG_MAX_BUF 1024
#define DELIM "="

struct config_s {
    char *key[MAXLEN];
    char *value[MAXLEN];
};

void read_config_file(struct config_s *conf, char *filename, int *size_of_array);

int main() {
    int i = 0, size_of_array;
    // type config_s has key and value members
    struct config_s c;

    read_config_file(&c, "test.cfg", &size_of_array);
    printf("size of array: %i\n", size_of_array);

    // if i want to print them all out, i can use this, but i'll have 
    // a function to search for a certain key and return the value.
    int l = 0, e = 1;
    printf("********** TEST 1 ***********\n");
    printf("key: [%s] value: [%s] i: [%i]\n", c.key[l], c.value[l], l);
    printf("key: [%s] value: [%s] i: [%i]\n", c.key[e], c.value[e], e);
    printf("********** TEST 2 ***********\n");

    return 0;
}

void read_config_file(struct config_s *conf, char *filename, int *size_of_array) {
    FILE *file;
    file = fopen(filename, "r");

    char line[CONFIG_MAX_BUF];

    int i = 0;

    char *cfline;
    char *key;
    char *value;

    while(fgets(line, sizeof(line), file) != NULL) {
        cfline = strstr((char *)line, DELIM);
        value = cfline + strlen(DELIM);
        value[strlen(value) - 1] = '[=11=]';

        key = strtok((char *)line, DELIM);
        printf("%i %s %s\n", i, key, value);
        conf->key[i]   = key;
        conf->value[i] = value;
        printf("%i %s %s\n", i, (*conf).key[i], (*conf).value[i]);
        i++;
    }
    printf("%s %s\n", (*conf).key[0], (*conf).value[0]);
    fclose(file);
    *size_of_array = i;
    return;
}

test.cfg

server=example.com
port=443
file=food.txt

您的代码中可能存在不止一个问题。我可以在 get_value_by_key 函数中看到其中一个。在这里,您将 conf->key[i]key 进行比较,这永远不会是真的(因为您正在比较两个不同的指针)。相反,您想要做的是:

if(strncmp(conf->key[i], key, strlen(conf->key[i])+1) == 0) 

比较这两个指针指向的两个字符串。

char *get_value_by_key(config_s *conf, char *key, int config_size) {
    int i;
    for(i=0;i<config_size;i++) {
        /*if(conf->key[i] == key) {*/ //Instead of this
        /* Do this */
         if(strncmp(conf->key[i], key, strlen(conf->key[i])+1) == 0) {
            return conf->value[i];
         }
    }
    /* Also return NULL if there is no match */
    return NULL;
}

在您最新版本的 read_config_file 中,您正在保存指向指向 的值的指针 缓冲区 line,位于 stack,所以这些指针将在return.

时失效

即使缓冲区是全局的,每一行的指针也会相互冲突,因为每次 fgets 调用都会覆盖缓冲区。

变化:

conf->key[i]   = key;
conf->value[i] = value;

进入:

conf->key[i]   = strdup(key);
conf->value[i] = strdup(value);