2010-03-13 90 views
6

爲什麼此代碼崩潰? 對字符指針是否使用strcat非法?爲什麼此代碼崩潰?

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char *s1 = "Hello, "; 
    char *s2 = "world!"; 
    char *s3 = strcat(s1, s2); 
    printf("%s",s3); 
    return 0; 
} 

請給出一個正確的方法來引用數組和指針。

+2

。它將第二個字符串附加到第一個字符串的末尾。它返回的字符串只是一個方便。你不能改變一個常量字符串(你的s1),這就是它崩潰的原因。 s1指向只讀內存。 – 2010-03-13 05:08:22

+14

如果一切都很好,代碼不會崩潰。 – 2010-03-13 05:08:35

+1

您可能想編輯您的問題,Ashish。你可能會因爲你說「甚至一切都很好」而獲得低價。不過,這是一個非常有效的問題。 – 2010-03-13 05:17:51

回答

11

問題是s1指向一個字符串字面值,並且您試圖通過向其添加s2來修改它。您不允許修改字符串文字。您需要創建一個字符數組和字符串都複製到它,就像這樣:

char *s1 = "Hello, "; 
char *s2 = "world!"; 

char s3[100] = ""; /* note that it must be large enough! */ 
strcat(s3, s1); 
strcat(s3, s2); 
printf("%s", s3); 

「足夠大」是指至少strlen(s1) + strlen(s2) + 1+ 1是爲了說明空終止符。

話雖如此,你應該認真考慮使用strncat(或者可以說是更好的,但是非標準strlcat,如果可用),這是邊界檢查,因而遠遠優於strcat

+0

可變長度數組(c99)或小於100的任何數值! :P – 2010-03-13 06:32:49

+0

是'strcat'返回第一個參數的原因是就像這樣一個情況下,便利 - 這意味着你可以做一條線串聯起來:'的strcat(strcat的(S3,S1),S2);' – caf 2010-03-13 07:49:51

+0

我實際上,在幾乎所有這種情況下,實際上更喜歡snprintf到strncat。這是一個小小的性能問題,但由於strncat的正確用法與庫的其餘部分不一致,因此更有可能被正確使用。 ('n'的含義與人們想象的不同。) – 2010-03-13 08:17:15

2

在這種情況下,正確的方法是在目標字符串(s1)中分配足夠的空間來存儲6個額外字符(s2)以及該字符串的空終止符。

char s1[14] = "Hello, "; 
char *s2 = "world!"; 
char *s3 = strcat(s1, s2); 
printf("%s",s3); 
0

下面是從strcat的()手動報價道:「的strcat()函數將在src字符串到DEST串,覆蓋在dest的端部的空字節(‘\ 0’),並然後添加一個終止的空字節,這些字符串可能不會重疊,並且dest字符串必須有足夠的空間用於結果。「

這裏的問題是,s1和s2指向「只讀」的靜態字符串,因此如果您嘗試在dest參數中使用這樣的字符串執行strcat操作,將會出現錯誤。

在這裏創建你好世界字符串的最好方法是malloc它,因此它將能夠包含s1和s2。另外,不要忘記在printf格式字符串的末尾添加'\ n',否則您可能會感到驚訝。

下面是代碼,如果我是你,我會寫:


int main() 
{ 
    char* s1 = "Hello "; 
    char* s2 = "World !"; 
    char *s3 = malloc((strlen(s1) + strlen(s2) + 1) * sizeof(char)); 
/* +1 is for the null terminating character 
and sizeof(*s3) is the actual size of a char. */ 

    if (s3) 
    { 
    strcat(s3, s1); 
    strcat(s3, s2); 
    printf("%s\n", s3); 
    free(s3); // always free what you alloc when you don't need it anymore. 
    } 
    return 0; 
} 
您正在使用的strcat錯誤