Подтвердить что ты не робот

Статическая строка литеральной таблицы?

Каков правильный способ в С++ для создания глобальной и статической таблицы строк?

Под "global" я имею в виду: Используется из любого файла, который включает заголовок. Но не часть некоторого времени исполнения, созданного singelton objcet.

Под "статикой" я имею в виду: как можно немного времени для запуска. Данные на страницах только для чтения. Только 1 экземпляр данных для каждого приложения.

Под "string" я имею в виду: Null завершенный массив символов хорош. std::string было бы неплохо, но я не думаю, что это можно сделать с точки зрения вышеизложенного. Правильно?

Под "таблицей" я имею в виду: я имею в виду индексируемый массив. Поэтому я не думаю, что это таблица. Но я гибкий в этом вопросе. Открыт для идей.

Под "С++" я имею в виду: С++ не C. (Обновление: С++ 98, а не С++ 11)

4b9b3361

Ответ 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]);

Или что-то в этом роде.