C - 从.INI文件中读取并将值传递给vars

时间:2018-01-20 04:21:51

标签: c string file ini

我正在为学校做一个项目,我需要从.INI文件中读取以开始我的游戏。问题是,我似乎无法理解strtok是如何工作的,而且我现在真的很困惑。

我知道我正在返回一个空结构,因为我不知道如何将特定值放入变量中!

这是我的read_from_config.h

#ifndef READ_FROM_CONFIG_H
#define READ_FROM_CONFIG_H
#define MAXSTR 500

typedef struct {
  unsigned int xdim;
  unsigned int ydim;
  unsigned int nzombies;
  unsigned int nhumans;
  unsigned int nzplayers;
  unsigned int nhplayers;
  unsigned int turns;
} CONFIG;

CONFIG read_config(char *argv[]);

#endif

这是我的read_from_config.c

#include "read_from_config.h"
#include "example.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

CONFIG read_config(char *argv[]) {
  char str[MAXSTR];
  FILE *fp = NULL;
  char *filename = argv[1];
  char *token;

  fp = fopen(filename, "r");
  if (fp == NULL) {
    fprintf(stderr, "Não foi possível abrir ficheiro de configuração.");
    fprintf(stderr, "\nModo de uso: ./program_name config.ini");
  }

  while (fgets(str, MAXSTR, fp) != NULL) {
      for (int i = 0; i != '\0'; i++) {
        char *equal = strpbrk (str, "=");
        if (equal) {
          token = strtok(str, "=");
        }
      }
  }
  printf("%d", token[0]);
  CONFIG config;
  return config;
}

CONFIG.INI

; Dimension of the grid
xdim=20
ydim=20
; Inicial number of zombies and humans
nzombies=20
nhumans=20
; Number of zombies and humans controlled by players
nzplayers=0
nhplayers=1
; Number of maximum turns
maxturns=1000

1 个答案:

答案 0 :(得分:2)

函数strtok仅在第一次调用时才接受字符串。 所有 后续调用必须与NULL

一起传递
  

man strtok

#include <string.h>
char *strtok(char *str, const char *delim);
     

<强>描述

     

strtok()函数将字符串分解为零个或多个非空标记的序列。   在第一次调用strtok()时,应在str中指定要解析的字符串。   在应解析相同字符串的每个后续调用中,str必须为NULL

示例:

char line[] = "a,b,c,d,e,f\n"; // to simulate an fgets line
char *token = strtok(line, ",\n");  // you can add \n to the separator
                                    // to get rid of the \n at the end

puts(token); // prints a
while(token = strtok(NULL, ",\n"))
    puts(token);  // prints b then c etc..

请记住strtok修改了源代码,这将失败:

strtok("a,b,c", ",");

因为字符串文字不可修改。在这种情况下,你必须复制 到char[]或动态分配的char*

如果你需要在解析后保持源完好,那么你肯定是 需要复制。

在您的代码中,您可以:

printf("%d", token[0]);

这不是不正确的,但可能不是你想做的。这条线不是 打印第一个字符,它打印第一个字符的ascii值。

printf("%c", token[0]);

将打印第一个字符。

你也在做

CONFIG read_config(char *argv[]) {
    ...
    CONFIG config;
    return config;
}

您正在返回未初始化的CONFIG对象,您忽略了解析 并且您的配置对象中没有设置任何内容。

你的解析也有点奇怪。

for (int i = 0; i != '\0'; i++)

循环立即退出,因为0 == '\0'!我不明白你是什么 试图用它。

我首先创建一个辅助函数来填充配置的值,参见 set_config_val。然后你可以像这样解析它:

CONFIG read_config(char *argv[]) {
    ...

    const char *delim = "=\n";
    CONFIG config;

    while (fgets(str, MAXSTR, fp) != NULL) {

        if(strchr(str, '='))
        {
            char varname[100];
            int value;

            token = strtok(line, delim);
            strcpy(varname, token);

            token = strtok(NULL, delim);
            value = atoi(token);

            set_config_val(&config, varname, value); 
        } else {
            fprintf(stderr, "Skipping line, no = found");
        }

    }

    fclose(fp);
    return config;
}


void set_config_val(CONFIG *config, const char *key, int val)
{
    if(config == NULL)
        return;

    if(strcmp(key, "xdim") == 0)
        config->xdim = val;
    else if(strcmp(key, "ydim") == 0)
        config->ydim = val;
    ...
}