@16tons addresses the most obvious issue,但有潛伏的記憶問題。 scanf
和strcat
調用容易受到buffer overflows的影響。他們不會僅限於分配的內存。
for(i=0;i<n;i++)
{
scanf("%s%s",name[i],sur[i]);
}
這將試圖把任何數量的輸入字符到name[i]
和sur[i]
這隻能分別持有的63首14個字符的字符串。這意味着Hubert Wolfeschlegelsteinhausenbergerdorff將導致name[i]
包含"Hubert\0"
和sur[i]
將包含"Wolfeschlegelst"
(無空字節),其餘將溢出到相鄰的內存導致問題。由於缺少空字節,試圖使用sur[i]
作爲字符串將導致讀取它後面的任何垃圾。
同strcat
。
for(i=0;i<n;i++)
{
a[0]=' ';
a[1]='\0';
strcat(name[i],a);
strcat(name[i],sur[i]);
}
如果name[i]
已滿,增加了年底便會溢出它的緩衝區塗鴉在相鄰的內存,造成怪異的問題。
How many names? 3
Enter names:
Hubert Wolfeschlegelsteinhausenbergerdorff
Hubert Wolfeschlegelsteinhausenbergerdorff
Hubert Wolfeschlegelsteinhausenbergerdorff
The names are:
Hubert WolfeschlegelstWolfeschlegelstWolfeschlegelsteinhausenbergerdorff WolfeschlegelstWolfeschlegelsteinhausenbergerdorff
gerdorff WolfeschlegelstWolfeschlegelsteinhausenbergerdorff
Hubert Wolfeschlegelsteinhausenbergerdorff
爲了避免這種情況,scanf
必須限制在緩衝區的大小。當使用strcat
時,要添加的字符串必須有足夠的空間來接受新字符。
由於您使用name[i]
來存儲名字和全名,所以重要的是限制名字的大小以便最後留出空間。由於sur[i]
可以有14個字符,而name[i]
可以有63個,即63 - 14或49.不要忘記空間! 48.
for(i=0;i<n;i++)
{
scanf("%48s%14s",name[i],sur[i]);
}
這確保scanf
將讀取不超過48個字符到name[i]
(使用,因爲空字節的49個字節)和不超過14到sur[i]
(使用15)。
現在你的strcat
是安全的。我們知道肯定有name[i]
有空間接受空間和sur[i]
結束。 48(最大字符數已經在name[i]
)+ 1(空格)+14(最大在sur[i]
)+1(空字節)= 64。
雖然你的技術可以節省一些內存,它的多安全有單獨given
和surname
變量,連接成一個新的name
變量。然後,你需要做的就是將given
,surname
的大小加起來,並且知道空間應該是多大的name
。 scanf
的限制只是緩衝區的大小。不需要記住,如果surname
變得更大,則一個變量必須保留一些額外的空間,也不必重做所有這些計算(或者更可能忘記重做它們)。
爲了您的特定目的,strcat
是不必要的。 printf
可以做到更安全。
printf("\nThe names are:\n");
for(i=0;i<n;i++)
{
printf("%s %s\n",name[i], sur[i]);
}
將一串變量打印到流中比將它們連接在一起然後將其打印出來更安全,更容易和更快速。
'a [3] ='';'在你的代碼中是problamatic。使用'a [0]'並將'a [1]'設爲NULL – 16tons
打開編譯器警告(通常通過添加'-Wall')。他們會抓住像'a [3] ='''這樣的問題。 – Schwern