我希望在编译时找到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
的长度?
在这个问题Determining the Length of a String Literal中,有一条注释要将数组声明为header_left[][4]
。我不想使用这种声明,因为在不改变数量常量的情况下,字符串的数量有变化的趋势。我喜欢让编译器计算字符串的数量(参见rows_in_header
定义)和每个字符串的长度。
这适用于嵌入式系统,字符串块写入到串行端口。串行端口功能将指向数据的指针和数据长度作为参数。串行端口代码针对块写入进行了优化。首选项不是使用strlen
,因为这会浪费性能时间。
我在ARM7TDMI平台上使用C99和IAR Embedded Workshop
我已经包含c++
标记,因为这也涉及C ++,我们将在首次产品发布后将代码迁移到C ++。
答案 0 :(得分:4)
如果您愿意,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());
}
答案 1 :(得分:1)
实际上,链接答案中的建议是错误的。因为它有索引反转。宣言应该更符合这一点:
static const char header_left[][40] =
{
" | | Raw | Raw |",
" | | Start | End |",
"Interval#| Duration | Point | Point |",
"---------+----------+-------+-------+",
};
最左边的索引仍然可以由编译器提供,并指示字符串的数量。字符串本身必须是一个固定的char数组,你可以提供一个上限(在本例中为40)。如果任何字符串超过该长度(包括null终止符),您将收到编译错误。您的目的的潜在缺点是浪费空间。
无论如何,你不能让编译器为你推断出两种尺寸 - 两种数组的尺寸 - 并且C ++中不支持锯齿状数组。
答案 2 :(得分:1)
宏魔法! (&gt; = C99) 至少需要2行。
注意我这里不使用char const*
,而是使用char const[...]
,即数组,因为它可以并且保证所有行具有相同的长度。
编辑:从length_of_row
减去-1以摆脱'\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
char数组的无界数组;与typedef char const row[length_of_row]; row header_left[] = {...};
答案 3 :(得分:0)
您可以提取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;