是否可以从C中读取文件中的常量?

时间:2017-10-15 11:30:41

标签: c file

我有一个名为definitions.h的文件,如下所示:

#define PACKAGE 270
#define IMPORT 271
#define COMILLAS 272
#define FUNCION 273
...

我有一个包含下一个信息的文本文件:

PACKAGE package
IMPORT import
COMILLAS "
FUNCION func

是否有可能以允许我在两个数组中加载常量本身和小写字的方式读取第二个文件?在一个数组中,它将是PACKAGE,IMPORT与其定义的值相关联,在第二个中是小写单词(package,import,",func)

我尝试将大写单词作为字符串阅读,但我不知道如何将它们更改为常量。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

为此,您的程序必须包含要翻译的每个名称的字符串值。不只是宏,它们在编译的早期就被转换为它们的值,没有留下你在那里使用的名字的痕迹。

所以你需要一个文件,比如definitions.c,包含类似的东西:

struct TokenNameEntry {
    int value;
    const char* name;
};

const struct TokenNameEntry tokens[] = {
    { PACKAGE, "PACKAGE" },
    { IMPORT, "IMPORT" },
    { COMILLAS, "COMILLAS" },
    { FUNCION, "FUNCION" },
    // ...
};

但是不要重复自己呢?现在,如果添加或删除任何常量,则需要更新definitions.h和definitions.c。

为了使这更好,我喜欢使用"宏文件"。这只包含一个或多个宏的重复使用,以便其他文件可以定义宏并使该文件说出它包含的数据的各种内容。我们将此文件称为definitions_macros.h:

/* definitions_macros.h
 * NO INCLUDE GUARD: A file may redefine the macros and include
 * more than once. */
DEFINE_TOKEN(PACKAGE, 270)
DEFINE_TOKEN(IMPORT, 271)
DEFINE_TOKEN(COMILLAS, 272)
DEFINE_TOKEN(FUNCION, 273)
// ...

然后,definitions.h将改为看起来像:

#ifndef CONST_DEFINITIONS_H_
#define CONST_DEFINITIONS_H_

#define DEFINE_TOKEN(symbol, value) symbol = value,
typedef enum {
#include "definitions_macros.h"
} TokenType;
#undef DEFINE_TOKEN

const char* token_to_name(TokenType tok);
TokenType token_from_name(const char* name);

#endif

而definitions.c变为:

#include "definitions.h"

struct TokenNameEntry {
    TokenType value;
    const char* name;
};

#define STRINGIFY_NOEXPAND(x) #x
#define STRINGIFY(x) STRINGIFY_NOEXPAND(x)
#define DEFINE_TOKEN(symbol, value) { symbol, STRINGIFY(symbol) },
const struct TokenNameEntry tokens[] = {
#include "definitions_macros.h"
};
#undef DEFINE_TOKEN
const unsigned int num_tokens = sizeof(tokens)/sizeof(tokens[0]);

const char* token_to_name(TokenType tok) {
    // TODO!
}

TokenType token_from_name(const char* name) {
    // TODO!
}

现在你有办法从你从文件中的一行读取的字符串到你想要存储的数字值来表示它。您可以在一个位置轻松更改这些常量标记的列表或值。如果还有什么需要用所有这些值(可能是一个switch语句?)做一些强烈模式化的东西,你可以重用相同的宏文件。如果要将更多数据与这些常量相关联,可以向DEFINE_TOKEN宏添加更多参数。