我在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
爲什麼是這種情況?
我在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
爲什麼是這種情況?
b
未初始化:它包含程序運行時RAM中的內容。
對於第一個字符串a,長度爲5,因爲它應該是「你好」有5個字符。
對於第二個字符串,b將其聲明爲包含5個字符的字符串,但您不初始化它,因此它會計數字符,直至找到包含0終止符的字節。
UPDATE:之後我寫了原來的答覆中加入下面的一行。
strncpy(b,a,length);
此問題之後,問題是您聲明b的大小長度,而它應該是長度+ 1爲字符串終結符提供空間。
謝謝先生,我是一個C noob。 haha –
但是當b初始化指向一個緩衝區? –
其他人已經指出,您需要爲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
一起被保留執行。]
實際上char數組並沒有以'\ 0'結尾,因此strlen無法知道它在哪裏停止計算字符串長度,因爲它的語法是int strlen(char * s) - >它不返回。的字符串直到'\ 0'(NULL字符) 所以爲了避免這個,我們必須追加NULL char(b [length] ='\ 0')
否則strlen count字符串中的字符傳遞直到NULL counter遇到
使用'size_t'來代替字符串長度'int'。 –
我做了,但輸出仍然相同。 –
這將是,但一般來說,對字符串長度和數組/對象大小使用plain(signed)'int'是不正確的。 'size_t'是無符號的(所以沒有-1長度的對象),並保證是你的平臺的正確尺寸(在64位系統中'size_t'將是8字節,而'int'可能只有4,這是肯定的最終導致問題)。另外,要打印'size_t'類型,請使用'「%zu」'。 –