2013-05-01 82 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

相關問題