2011-08-10 55 views
2

我正在學習c中的字符串。我使用code :: blocks作爲編譯器,即使它不僅僅適用於c。所以,下面代碼的問題是string2的輸出是存儲的5個字符加上string1的輸出。我會告訴你:在C中複製字符串

#include <stdio.h> 
#include <string.h>   /* make strncpy() available */ 

int main() 
{ 
char string1[]= "To be or not to be?"; 
char string2[6]; 

/* copy first 5 characters in string1 to string2 */ 
strncpy (string2, string1, 5); 

printf("1st string: %s\n", string1); 
printf("2nd string: %s\n", string2); 
return 0; 
} 

輸出是:

1st string contains: To be or not to be? 
2nd string contains: To be To be or not to be? 

如果你問我,這比5個字符多了很多......

回答

3

您還沒有終止字符串2與「\ 0」,所以printf的超支。試着做:

memset(string2,0,6); 

在使用string2之前。 或者,因爲你知道你要複製5個字符,strncpy()函數後:

string2[5] ='\0'; 

所以你正確正確終止字符串。

注意一個事實,即應該在複製後的字符數之後加'\ 0',否則即使在字符串中間也會看到垃圾。

+0

謝謝。我認爲第二種選擇超出了我的想法,但是我能夠在程序中正確使用第一個選項。非常感激。 :)可愛的寶寶,順便說一句。 –

+0

@Michael第二個選項比較好,它基本上在字符串中最後一個重要字符之後加上'\ 0'。謝謝 ;) –

10

strncpy手冊頁:

沒有空字符被隱式地追加到目的地的末尾,所以如果C的長度源中的字符串小於num。

由於原始字符串的長度大於5,因此不會添加NULL。

正如其他人所指出的,一些安全添加到它:

strncpy (string2, string1, sizeof(string2)); 
string2[sizeof(string2)-1] = '\0'; 

注意,如果string2通過malloc()獲得:

char * string2 = malloc(123); //sizeof(string2) == sizeof(void *) and not 123 

而且上面的代碼會失敗。

爲了完整起見,這裏是代碼:http://ideone.com/eP4vd

+0

因此,不使用strncpy()函數,它是不安全的。 – Tom

+0

要清楚,OP,你應該添加'string2 [5] ='\ 0';'這將正確地終止字符串。如果沒有null,你的'printf'不知道字符串何時結束,所以它一直在讀取內存直到找到它。 – dcpomero

+2

@Tom,大多數人認爲C不安全的東西對於不知道自己在做什麼的人來說只是不安全的。他們應該堅持使用BASIC :-)有一些例外(例如'gets'或'scanf'帶有無界的'%s'格式說明符),但絕大多數對於那些知道如何使用它們的人來說都很好。 – paxdiablo

0

您的string2不包含\0因此此字符串未終止。當您打印它時,它會超出範圍並打印它在其中找到的任何東西,直至找到\0

在每個strncpy之後,如果您想要正確終止字符串,則必須手動插入\0

1

基本上兩個字符串在堆棧上彼此相鄰的存儲器,並且不存在空終止字符串2之後,所以,當它的打印它的打印「要」從string2 +隨機的一個字節值(string2[5])+ string1 (「成爲或不成爲」),然後敲擊空字節。

如果那個隨機的一個字節值是0,它會停止。你會得到你期望的印刷品。

0

strncpy有侷限性,請參閱上文。 看看sprintf的像

sprintf(string2, "%.*s", sizeof(string2)-1, string1); 
0

strncpy(),儘管它的名字,是不是簡單的strcpy()一個更安全的邊界指定的版本。這是一個含糊不清的語義的模糊函數,我認爲它不應該包含在C標準庫中。

strncat()另一方面,strcat()的更安全的邊界指定版本。

這裏有一個解決方案:

char string1[]= "To be or not to be?"; 
char string2[6]; 

string2[0] = '\0'; 
strncat (string2, string1, 5);