2013-01-08 58 views
12

在C++中创建全局字符串静态表的正确方法是什么?静态字符串文字表?

“全局”,我的意思是:可以从包含头文件的任何文件中使用。但不是某些运行时创建的singelton objcet的一部分。

“静态”,我的意思是:尽可能少的运行时间设置可能。只读内存页中的数据。每个应用只有1个数据实例。

通过“字符串”,我的意思是:空终止的字符数组是罚款。 std :: string会很好,但我不认为这可以用上面的方法来完成。正确?

“表”,我的意思是:我的意思是一个可索引的数组。所以我猜这不是一张桌子。但在这一点上我很灵活。打开想法。

通过 “C++”,我的意思是:C++未C.(更新:C++ 98,而不是C++ 11)

+1

你是什么意思表? – Pubby

+0

全局数组? 'const char * table [SIZE];' –

+0

我不认为_C_ vs _C++ _会在这里给出很大的区别,因为'std :: string'没有问题... –

回答

6

使用字符串文字的std::array。它没有构造函数,因此它将像C数组一样在.rodata节中静态加载,但它具有标准的C++库接口。 (迭代器,大小等)

A.H

#include <array> 

extern std::array<const char*, 3> A; 

A.cpp

std::array<const char*, 3> A = { "foo", "bar", "baz" }; 

http://en.cppreference.com/w/cpp/container/array

+0

这很可惜,这需要元素数重复,但值得我认为对于std :: array的好处。 –

+0

虽然(在接口方面)'char const *'不太好。根据编译器的C++ 11性质,我相信可以在'array_ref'的模型上建立一个'constexpr'构造函数的类,例如[在此建议](http://www.open- std.org/jtc1/sc22/wg21/docs/papers/2012/n3334.html)。 –

+0

有没有一个C++ 98的方法来做到这一点? (除了@WhozCraig建议的) – nonot1

9

strings.h

extern const char* table[]; 

strings.cpp

const char* table[] = { 
    "Stack", 
    "Overflow", 
} 

另取在此,使用错误代码的查找表:

err.h

#define ERR_NOT_FOUND 0x1004 
#define ERR_INVALID  0x1005 

bool get_err_msg(int code, const char* &msg); 

err.cpp

typedef struct { 
    int errcode; 
    const char* msg; 
} errmsg_t; 

static errmsg_t errmsg_table[] = { 
    {ERR_NOT_FOUND, "Not found"}, 
    {ERR_INVALID, "Invalid"} 
}; 

#define ERRMSG_TABLE_LEN sizeof(errmsg_table)/sizeof(errmsg_table[0]) 

bool get_err_msg(int code, const char* &msg){ 
    msg = NULL; 
    for (int i=0; i<ERRMSG_TABLE_LEN; i++) { 
     if (errmsg_table[i].errcode == code) { 
      msg = errmsg_table[i].msg; 
      return true; 
     } 
    } 
    return false; 
} 

的main.cpp

#include <stdio.h> 
#include "err.h" 

int main(int argc, char** argv) { 
    const char* msg; 
    int code = ERR_INVALID; 
    if (get_err_msg(code, msg)) { 
     printf("%d: %s\n", code, msg); 
    } 
    return 0; 
} 

我敢肯定有这样做的更多的C++的方式,但我真的一个C程序员。

+0

为什么'extern'? – Pubby

+2

因为它会被其他C文件包含吗? –

3

严格规定,以确保您的table_n至少有一个暗示它有多大:

表。^ h

// header file 
extern const size_t table_n; 
extern const char* table[]; 

Table.cpp

// c/cpp file 
const char *table[] = 
{ 
    "one", 
    "two", 
    "there" 
}; 

const size_t table_n = sizeof(table)/sizeof(table[0]); 

或者类似的东西。

4

我喜欢乔纳森·莱因哈特的方式,我总是这样做的,特别是如果我们有要素的结构,

但是

,它需要一个循环来找到元件(未编入索引), 所以如果你喜欢的改进,特别适用于嵌入式系统风格。

enum ERR_INDEX{ 
ERR_NOT_FOUND=0, 
ERR_INVALID, 
ERR_BAD_LENGTH, 
ERR_MORE_ERR1, 
ERR_MORE_ERR2, 
ERR_MORE_ERR3, 
}; 

static const char * errmsg_table[] = { 
    "Not found", 
    "Invalid", 
    "bad message length", 
    "error 1", 
    "error 2", 
    "error 3", 
}; 

int main(int argc, char** argv) { 
    int code = ERR_INVALID; 
    printf("%d: %s\n", code, errmsg_table[code]); 
    printf("%d: %s\n", code, errmsg_table[ERR_BAD_LENGTH]); 

return 0; 
} 
+2

这适用于从0开始并按1递增的错误代码。 – aah134

+2

而*仅*用于这样的错误代码。 –

+2

如果您有更多的错误代码不是按顺序排列的,那么您可以有一个将错误代码转换为顺序列表的字典,或者只是将错误代码作为关键字的字典以及错误消息作为字符串:) – aah134

相关问题