2011-10-02 135 views
0

我在C下面的一段代碼:錯誤strlen的輸出

char a[55] = "hello"; 
size_t length = strlen(a); 
char b[length]; 
strncpy(b,a,length); 
size_t length2 = strlen(b); 
printf("%d\n", length);   // output = 5 
printf("%d\n", length2);   // output = 8 

爲什麼是這種情況?

+1

使用'size_t'來代替字符串長度'int'。 –

+0

我做了,但輸出仍然相同。 –

+0

這將是,但一般來說,對字符串長度和數組/對象大小使用plain(signed)'int'是不正確的。 'size_t'是無符號的(所以沒有-1長度的對象),並保證是你的平臺的正確尺寸(在64位系統中'size_t'將是8字節,而'int'可能只有4,這是肯定的最終導致問題)。另外,要打印'size_t'類型,請使用'「%zu」'。 –

回答

9

它必須是'b [length +1]' strlen在c字符串的末尾不包含空字符。

+4

也需要添加'b [length] ='\ 0''。 – tia

+4

..或者使用'strncpy(b,a,length + 1)',只要知道在a [length]處(或之前)有一個空字符' – Dmitri

4

你從來沒有初始化b任何東西。因此它的內容是未定義的。致strlen(b)的呼叫可能會超出b的大小,並導致未定義的行爲(例如崩潰)。

+0

...並且由於內容未定義,數組中可能會出現0。它打破了strlen。 – Griwes

+0

Sry我錯過了一行代碼,現在b已經初始化,但問題仍然存在。 –

+1

@Ronnie Slack:你能顯示初始化嗎? (評論它,以便我們知道已發佈的答案仍然相關) – Mysticial

2

b未初始化:它包含程序運行時RAM中的內容。

1

對於第一個字符串a,長度爲5,因爲它應該是「你好」有5個字符。

對於第二個字符串,b將其聲明爲包含5個字符的字符串,但您不初始化它,因此它會計數字符,直至找到包含0終止符的字節。

UPDATE:之後我寫了原來的答覆中加入下面的一行。

strncpy(b,a,length); 

此問題之後,問題是您聲明b的大小長度,而它應該是長度+ 1爲字符串終結符提供空間。

+0

謝謝先生,我是一個C noob。 haha –

+0

但是當b初始化指向一個緩衝區? –

1

其他人已經指出,您需要爲b分配strlen(a)+1字符才能保存整個字符串。

他們給了你一套用於strncpy的參數,這些參數將試圖掩蓋它並不真正適合手頭工作(或者幾乎任何其他被告知的事實)的事實。你真正想要的只是使用strcpy來代替。另請注意,但是,由於您已分配它,因此b也是本地(auto存儲類)變量。將字符串複製到局部變量中很少有用。

大多數情況下,如果您要複製字符串,則需要將其複製到動態分配的存儲中 - 否則,您可能會使用原始文件並跳過複製。將字符串複製到動態分配的存儲中非常普遍,因此許多庫已經包含一個用於此目的的函數(通常名爲strdup)。如果你的庫沒有的是,這也很容易寫一個你自己的:

char *dupstr(char const *input) { 
    char *ret = malloc(strlen(input)+1); 
    if (ret) 
     strcpy(ret, input); 
    return ret; 
} 

[編輯:我命名此dupstr因爲strdup(與別的開始str一起被保留執行。]

0

實際上char數組並沒有以'\ 0'結尾,因此strlen無法知道它在哪裏停止計算字符串長度,因爲它的語法是int strlen(char * s) - >它不返回。的字符串直到'\ 0'(NULL字符) 所以爲了避免這個,我們必須追加NULL char(b [length] ='\ 0')

否則strlen count字符串中的字符傳遞直到NULL counter遇到