如何创建一个由使用 strtok 函数创建的标记组成的数组?

How to create an array consisting of the tokens created using the strtok function?

我是 .ini 文件的新手,因此这个 qn(这可能看起来很傻)。我创建了一个 .ini 文件并通过我的 C 程序访问它。 ini 文件如下所示:

 [key]
 title = A,H,D

C 程序访问它使用:

 LPCSTR ini ="C:\conf.ini;
 char var[100];
 GetPrivateProfileString("key", "title", 0, var, 100, ini);

 printf("%s", var);
 char* buffer = strtok(var, ", ");
do{
    printf("%s", buffer);

    if (strcmp(buffer, "A")==0)
        printf("Hello");

    puts("");
}while ((buffer=strtok(NULL, ", "))!= NULL);

输出看起来像:

  A H D F G IAHello
  H
  D
  F
  G

现在我需要做的是再次使用这些单独的标记在我的 C 程序中形成一个带有索引的数组。例如:

  char x[A, H, D, F, G]

所以当我引用索引 2 时,x[2] 应该给我 'D'。有人可以建议一种方法来做到这一点。我以前从未使用过 strtok,因此很困惑。提前谢谢你。

这个问题与其他关于获取外部信息并将其存储在数组中的问题非常相似。

这里的问题是数组中要存储的元素数量。

你可以使用 Link-lists,但对于这个例子,我会扫描文件,获取数组所需的项目总数 - 然后再次解析文件数据 - 将项目存储在数组。

第一个循环遍历并计算要存储的项目,按照您发布的示例。我将执行第二个循环作为示例 - 请注意在我的示例中您将创建 nTotalItems 并计算项目的数量,将其存储在 nTotalItems 中......我假设您想要存储一个字符串,而不仅仅是一个 char ...

另请注意,这是一个在工作中完成的草稿示例 - 仅用于展示将标记存储到数组中的方法,因此没有错误检查 ec

 // nTotalItems has already been calculated via the first loop...
 char** strArray = malloc( nTotalItems * sizeof( char* ));
 int    nIndex  = 0;

 // re-setup buffer
 buffer = strtok(var, ", ");
 do {

     // allocate the buffer for string and copy...    
     strArray[ nIndex ] = malloc( strlen( buffer ) + 1 );
     strcpy( strArray[ nIndex ], buffer );

     printf( "Array %d = '%s'\n", nIndex, strArray[ nIndex ] );

     nIndex++;

 } while ((buffer=strtok(NULL, ", "))!= NULL);

只需使用an INI parser that supports arrays

INI 文件:

[my_section]
title = A,H,D

C程序:

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

#define MY_ARRAY_DELIMITER ','

struct configuration {
    char ** title;
    size_t title_length;
};

static char ** make_strarray (size_t * arrlen, const char * src, const size_t buffsize, IniFormat ini_format) {

    *arrlen = ini_array_get_length(src, MY_ARRAY_DELIMITER, ini_format);
    char ** const dest = *arrlen ? (char **) malloc(*arrlen * sizeof(char *) + buffsize) : NULL;
    if (!dest) { return NULL; }
    memcpy(dest + *arrlen, src, buffsize);
    char * iter = (char *) (dest + *arrlen);
    for (size_t idx = 0; idx < *arrlen; idx++) {
        dest[idx] = ini_array_release(&iter, MY_ARRAY_DELIMITER, ini_format);
        ini_string_parse(dest[idx], ini_format);
    }

    return dest;

}

static int ini_handler (IniDispatch * this, void * v_conf) {

    struct configuration * conf = (struct configuration *) v_conf;

    if (this->type == INI_KEY && ini_string_match_si("my_section", this->append_to, this->format)) {

        if (ini_string_match_si("title", this->data, this->format)) {

            /*  Save memory (not strictly needed)  */
            this->v_len = ini_array_collapse(this->value, MY_ARRAY_DELIMITER, this->format);

            /*  Allocate a new array of strings  */
            if (conf->title) { free(conf->title); }
            conf->title = make_strarray(&conf->title_length, this->value, this->v_len + 1, this->format);
            if (!conf->title) { return 1; }

        }

    }

    return 0;

}

static int conf_init (IniStatistics * statistics, void * v_conf) {

    *((struct configuration *) v_conf) = (struct configuration) { NULL, 0 };
    return 0;

}

int main () {

    struct configuration my_conf;

    /*  Parse the INI file  */
    if (load_ini_path("C:\conf.ini", INI_DEFAULT_FORMAT, conf_init, ini_handler, &my_conf)) {

        fprintf(stderr, "Sorry, something went wrong :-(\n");
        return 1;

    }

    /*  Print the parsed data  */
    for (size_t idx = 0; idx < my_conf.title_length; idx++) {

        printf("my_conf.title[%d] = %s\n", idx, my_conf.title[idx]);

    }

    /*  Free the parsed data  */
    if (my_conf.title_length) {

        free(my_conf.title);

    }

    return 0;

}

输出:

my_conf.title[0] = A
my_conf.title[1] = H
my_conf.title[2] = D