问题
What is the correct way in C++ to create a global & static table of strings?
By "global", I mean: Useable from any file that includes the header. But not part of some run-time created singelton objcet.
By "static", I mean: As little run time set up possable. Data in read only memory pages. Only 1 instance of data per app.
By "string", I mean: Null terminated array of chars is fine. std::string would be nice, but I don't think it can be done in terms of the above. Correct?
By "table", I mean: I mean an indexable array. So I guess not a table per-se. But I'm flexable on this point. Open to ideas.
By "C++", I mean: C++ not C. (Update: C++98, not C++11)
回答1:
strings.h
extern const char* table[];
strings.cpp
const char* table[] = {
"Stack",
"Overflow",
}
Another take on this, using error codes for a lookup table:
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;
}
I'm sure there is a more C++ way of doing this, but I'm really a C programmer.
回答2:
Use a std::array
of string literals. It has no constructor so it will be loaded statically in the .rodata
section like a C array, yet it has a standard C++ library interface. (iterators, size, etc)
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
回答3:
I like Jonathon Reinhart way, I always do it that way especially if we have a structure of elements,
however, it requires a loop to find the elements (Not indexed), so if you like an improvement, especially for embedded systems style.
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;
}
回答4:
The table_n
provided strictly to ensure you at least have a hint how big it is:
Table.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]);
Or something like that.
来源:https://stackoverflow.com/questions/14208412/static-string-literal-table