Статическая строка литеральной таблицы?
Каков правильный способ в С++ для создания глобальной и статической таблицы строк?
Под "global" я имею в виду: Используется из любого файла, который включает заголовок. Но не часть некоторого времени исполнения, созданного singelton objcet.
Под "статикой" я имею в виду: как можно немного времени для запуска. Данные на страницах только для чтения. Только 1 экземпляр данных для каждого приложения.
Под "string" я имею в виду: Null завершенный массив символов хорош. std::string было бы неплохо, но я не думаю, что это можно сделать с точки зрения вышеизложенного. Правильно?
Под "таблицей" я имею в виду: я имею в виду индексируемый массив. Поэтому я не думаю, что это таблица. Но я гибкий в этом вопросе. Открыт для идей.
Под "С++" я имею в виду: С++ не C. (Обновление: С++ 98, а не С++ 11)
Ответы
Ответ 1
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.
Ответ 2
Используйте std::array
строковых литералов. Он не имеет конструктора, поэтому он будет загружен статически в разделе .rodata
, как массив C, но он имеет стандартный интерфейс библиотеки С++. (итераторы, размер и т.д.)
хиджры
#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
Мне нравится метод Джонатона Рейнхарта, я всегда так делаю, особенно если у нас есть структура элементов,
однако для этого требуется цикл для поиска элементов (не проиндексирован),
поэтому, если вам нравится улучшение, особенно для стиля встроенных систем.
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
table_n
предоставляется строго для того, чтобы вы, по крайней мере, имели подсказку, насколько она велика:
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]);
Или что-то в этом роде.