Размер времени компиляции строкового литерала в массиве строковых литералов

Я ищу, чтобы найти длину литерала C-строки во время компиляции.
Учитывая определения:

static const char * const   header_left[] =
{
"         |          |  Raw  |  Raw  |",
"         |          | Start |  End  |",
"Interval#| Duration | Point | Point |",
"---------+----------+-------+-------+",
};
const unsigned int  rows_in_header = sizeof(header_left) / sizeof(header_left[0]);

Как мне найти длину строкового литерала header_left[2] без использования strlen?

В этом вопросе Определение длины строкового литерала, есть комментарий, чтобы объявить массив как header_left[][4], Я предпочитаю не использовать такого рода декларации, так как существует тенденция изменения количества строк без изменения количественной постоянной. Мне нравится, когда компилятор вычисляет количество строк (см. rows_in_header определение) и длина каждой строки.

Это для встроенной системы и строки блок написано к последовательному порту. Функция последовательного порта принимает указатель на данные и длину данных в качестве параметров. Код последовательного порта оптимизирован для блочной записи. Предпочтение не использовать strlen потому что это тратит время производительности.

Я использую C99 с IAR Embedded Workshop на платформе ARM7TDMI.
Я включил c++ тег, потому что это также включает в себя C ++, и мы будем мигрировать код в C ++ после первого запуска продукта.

1

Решение

На самом деле совет в связанном ответе неверен. поскольку это имеет обратные индексы. Декларация должна быть примерно такой:

static const char header_left[][40] =
{
"         |          |  Raw  |  Raw  |",
"         |          | Start |  End  |",
"Interval#| Duration | Point | Point |",
"---------+----------+-------+-------+",
};

Самый левый индекс все еще может быть предоставлен компилятором и указывает количество строк. Сами строки должны быть фиксированным массивом символов, для которого вы можете указать верхнюю границу (в нашем примере 40). Вы получите ошибку компиляции, если какая-либо строка превышает эту длину (включая нулевой терминатор). Потенциальным недостатком для ваших целей является потраченное впустую пространство.

В любом случае, вы не можете заставить компилятор выводить для вас оба размера — размер обоих массивов — и зубчатые массивы не поддерживаются в C ++.

1

Другие решения

Класс stringref может обработать это, если хотите. Это кажется проще, чем большинство других ответов, и обрабатывает ситуации, когда строки имеют различную длину:

struct stringref {
//this is for convenience, but isn't used in this sample
stringref(const char* p, size_t l=0) :ptr(p), len(l?l:strlen(p)) {}
//construct from string literals
template<size_t l> stringref(const char(&p)[l]) :ptr(p), len(l) {}
//convert to const char*
operator const char*() const {return ptr;}
const char* get() const {return ptr;}
//retrieve the length
size_t length() const {return len;}
private:
const char* ptr;
size_t len;
};

stringref header_left[] =
{
"         |          |  Raw  |  Raw  |   ",
"         |          | Start |  End  | ",
"Interval#| Duration | Point | Point |      ",
"---------+----------+-------+-------+",
};

int main()
{
const char* ptr = header_left[0]; //conversion possible
printf("%d\n", header_left[0].length());
printf("%d\n", header_left[1].length());
printf("%d\n", header_left[2].length());
printf("%d\n", header_left[3].length());
}

http://coliru.stacked-crooked.com/view?id=e244267379f84e21409db9ec39da5765-50d9cfc8a1d350e7409e81e87c2653ba

4

Макро магия! (> = C99)
Требуется минимум 2 ряда.

Обратите внимание, я не использую char const* но char const[...] здесь, то есть массивы, потому что это возможно и гарантирует, что все строки имеют одинаковую длину.

Изменить: вычесть -1 из length_of_row избавиться от '\0',

#include<cstddef>
#define CREATE_HEADER(X, ...) \
static const size_t length_of_row = sizeof(X)/sizeof(X[0]) - 1; \
static const char header_left[][length_of_row+1] = { X, __VA_ARGS__ }; \
static const size_t rows_in_header = sizeof(header_left) / sizeof(header_left[0]); \

CREATE_HEADER(
"         |          |  Raw  |  Raw  |",
"         |          | Start |  End  |",
"Interval#| Duration | Point | Point |",
"---------+----------+-------+-------+",
);

  • sizeof(X)/sizeof(X[0]) выдает длину первой строки (строки)
  • static const char header_left[][length_of_row] является неограниченным массивом массивов length_of_row обугливается; такой же как typedef char const row[length_of_row]; row header_left[] = {...};
1

Вы можете извлечь header_left[2] строка и использование sizeof(...) - 1

static const char header_left_2[] = "Interval#| Duration | Point | Point |";
static const char * const   header_left[] =
{
"         |          |  Raw  |  Raw  |",
"         |          | Start |  End  |",
header_left_2,
"---------+----------+-------+-------+",
};
const unsigned int  rows_in_header = sizeof(header_left) / sizeof(header_left[0]);
const size_t header_left_2_len = sizeof(header_left_2) - 1;
0
По вопросам рекламы [email protected]