2013-05-01 41 views
1

我正在编译时查找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

所以你不能改变的定义呢?例如。宏魔法或C++魔术.. – dyp 2013-05-01 18:06:29

+0

对于'static const char * const header_left []'而言,长度无关紧要,因为这是一个指针数组。你是否想要'static const char header_left [] [sizeof“Interval#| Duration | Point | Point |”] = {...};'? – 2013-05-01 18:06:34

+0

@DanielFischer:我需要复制你的案例中的文本,一次是'sizeof',另一次是'{'和'}'之间的时间吗? – 2013-05-01 18:13:06

回答

1

其实链接答案的建议是错误的。因为它具有相反的指标。该声明应多沿此线:

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

最左边的指数仍然可以通过编译器来提供,并指示字符串的计数。字符串本身必须是一个固定的字符数组,你可以提供一个上限(在本例中为40)。如果任何字符串超过该长度(包括空终止符),您将收到编译错误。你的目的潜在的缺点是浪费的空间。

无论如何,您不能让编译器为您推导出两种尺寸 - 两种数组的尺寸 - 并且C++中不支持锯齿状数组。

+0

如果数组中的每个元素都是固定长度的,它仍然被认为是*锯齿状数组* *? – 2013-05-01 18:16:36

+0

否 - 锯齿形数组是一个数组数组,其大小可变。在C++中,你实际上只有一维数组,其元素必须是固定的大小(编译时间)。这些可以嵌套以提供多维数组的近似值。但只有最重要的(最外面的)阵列可以推导出其大小。 – 2013-05-01 18:21:51

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; 
1

宏神奇! (> = 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炭的阵列的无界阵列;与typedef char const row[length_of_row]; row header_left[] = {...};
+0

http://coliru.stacked-crooked.com/view?id=7be12a566c06274fc6df138fd614e1bd-50d9cfc8a1d350e7409e81e87c2653ba比我预期的更好。 – 2013-05-01 18:31:17

+0

@MooingDuck也就是说,'-1'为'\ 0'我认为? – dyp 2013-05-01 18:33:12

+0

不,我认为你的回答是错误的,所以编码它,这是正确的。所以我为未来的怀疑者发布了代码。 – 2013-05-01 18:33:56

4

如果您愿意,stringref类可以处理这个问题。这似乎比大多数其他的答案更简单,并处理其中的行是两种不同长度situtations:

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

+0

哦,现在我注意到“我正在使用C99”这一行... – 2013-05-02 17:36:31

相关问题