金山面試的問題之一,比較簡單。
須要注意兩點:1.字符串空間檢測判斷2.字符串末尾記得加'0'html
也是個人答案:c++
char *strcat(char *str1, char *str2) { if((str1==NULL)||(str2==NULL)) throw "Invalide arguments!"; int len1=strlen(str1),len2=strlen(str2); for(int i=strlen(str1);i<len1+len2;i++){ str1[i]=str2[i-len1]; } str1 [len1+len2]= '\0'; return str1; }
當時少寫了 str1 [len1+len2]= '0';面試
char *strcat(char *str1, char *str2) { if((str1==NULL)||(str2==NULL)) throw "Invalide arguments!"; char *pt = str1; while(*str1!='\0') str1++; while(*str2!='\0') *str1++ = *str2++; *str1++ = '\0'; return pt; }
切不可寫成return str1;
由於此時函數體內的str1指針已經被移動到字符串結尾,指向'0'。
因此只能返回一開始pt保存的原始str1。返回值錯誤!數組
因爲函數strcat的參數str1是形參,因此主函數的數組a的指針不會變化。
可是最好的寫法仍是不要直接對str1作修改:ide
char *strcat(char *str1, char *str2) { if((str1==NULL)||(str2==NULL)) throw "Invalide arguments!"; char *pt = str1; while(*pt!='\0') pt++; while(*str2!='\0') *pt++ = *str2++; *pt = '\0'; return str1; }
參考:http://www.blog.chinaunix.net...
聲明:使用gcc和vc++(VS2010)編譯函數
函數定義:char *strcat (char *dest,const char *src)
函數說明:strcat()
會將參數src字符串拷貝到參數dest所指的字符串尾,第一個參數dest要有足夠的空間來容納要拷貝的字符串;
返回值: 返回dest字符串參數的起始地址;ui
接下來分三種狀況來看strcat()
函數:.net
#include <string.h> #include <stdio.h> int main(void) { char dest[30] = "Hello"; char src[] = "World"; strcat(dest, src); printf("dest:[%s]\n", dest); return 0; }
GCC/VC++:dest:[HelloWorld]unix
dest爲空指針
#include <stdio.h> #include <string.h> int main(void) { char *dest = NULL; char *src = "World"; strcat(dest, src); printf("dest:[%s]", dest); return 0; }
GCC:Segmentation fault (core dumped)居然是段錯誤,爲何呢?
dest沒有足夠的空間來存儲src中的內容;
VC++:
cmd:空 彈出:.exe已中止工做。
修改以後的:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *dest = NULL; dest = (char *)malloc(1024); *dest='\0';//顯式將首地址指向結束符。很是必要。不然1024個字節的字符串會充滿隨機的字符。 char *src = "World"; strcat(dest, src); printf("dest:[%s]", dest); return 0; }
GCC/VC++:dest:[World]
若是沒有*dest='\0';
,GCC經過,VC++不經過。
猜想:gcc在malloc後,新分配的空間自動補全了'0'。
dest非空
但此時的dest是空字符串,若是想要在非空字符串(好比"aaa")後strcat怎麼辦?
直接把char *dest = NULL;
改爲char *dest = "aaa";
嗎?
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *dest = "aaa"; dest = (char *)malloc(1024); *(dest+3)='\0'; char *src = "World"; strcat(dest, src); printf("dest:[%s]", dest); return 0; }
VC++:
cmd: dest:[屯蚖orld]
gcc:
dest[World]
VC++中, "aaa"被新分配的內存地址的值覆蓋。因爲新分配的內存地址的值並未初始化(除了dest+3位置上賦值爲'0'), 因此出現亂碼。"World"的第一個字母W(1字節)被a的第三個字符組合成了漢字「蚖」(2字節)。
那麼,先分配內存,而後賦值:char *dest = (char *)malloc(1024);dest = "aaa";
?
同樣不能夠!
VC++:
cmd:空 彈出:.exe已中止工做!
gcc:Segmentation fault (core dumped)
緣由相同:"aaa"將分配的空間覆蓋,也就是說a指向新的字符串"aaa",它的大小爲4,沒法放下a和b。
正確的作法是對a先申請內存,而後用strxxx函數對a開始幾位進行修改。好比用strcpy:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main () { char *dest=(char *)malloc(1024); char *src="World"; strcpy (dest,"aaa"); strcat (dest,src); printf("dest:[%s]", dest);//puts (dest); return 0; }
vc++:
cmd:dest:[aaaWorld]
gcc:
dest:[aaaWorld]
OK!
#include <stdio.h> #include <string.h> int main(void) { char dest[6] = "Hello"; char *src = "World"; strcat(dest, src); printf("dest:[%s]\n", dest); return 0; }
gcc:
dest:[HelloWorld] *** stack smashing detected ***: ./1 terminated Aborted (core dumped)
爲何會這樣呢?不是說要空間足夠的時候才能夠拷貝成功的麼?
很明顯,這屬於數組越界的問題,在C語言中,c不檢查也不提示,因此這裏的拷貝用到了dest[6]後面緊挨着的幾個存儲單元;
VC++:
cmd:dest:[HelloWorld] 彈出:stack around the variable 「XX」 was corrupted!
#include <stdio.h> #include <string.h> int main(void) { char *dest; char src[] = "World"; strcat(dest, src); printf("dest:[%s]\n", dest); return 0; }
看到這裏,都會知道確定是dest的空間不足,沒法拷貝src中的內容;
因此輸出結果是:
gcc:
dest:[�Ax�World] //原文說他的結果是Segmentation fault (core dumped)
vc++:
cmd:空。 彈出:dest未初始化就被使用。
更改以後:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *dest; dest = (char *)malloc(1024); *dest='\0'; char src[] = "World"; strcat(dest, src); printf("dest:[%s]\n", dest); return 0; }
OK輸出結果是
GCC/vc++:dest:[World]
若是沒有*dest='\0';
,GCC經過,VC++不經過。