0

ポインタを使用して2つの文字列を連結する関数を作成しました。strcat(s、t)と同様に、sの最後にtが追加されます。

   int main ()
{
  char b[] = "Hello";
  char b1[] = "world";
  string_cat(b,b1);
  printf("Concatenated string is %s\n",b);
  return 0;
}
int string_cat(char *s, char *d)
{
  while(*++s != '\0')
    ;
  *s++ = ' ';
  while((*s++ = *d++)!='\0');  // Concatenation
  printf("S is %c\n",s[-2]);   // Just to see the values
}

連結は正常に機能しますが、要素の格納方法を確認したい場合、すべての要素が負の方向に格納されます。つまり、s[-2]は'd'に等しく、s[-3]は'l'に等しくなります。 。これはそれらが保存される方法ですか?

4

2 に答える 2

3

最初のアップbは、連結された文字列を保持するには小さすぎます。それは保持するのに十分なスペースしかないHello\0ので、あなたがしていることは未定義です。次に、次の行を見てください。

while((*s++ = *d++)!='\0');
        ^^^

あなたはそれを増やしているsのであなたは前進しています。あなたがそれを増やすたびに、あなたはそれが1つの要素を前方に向けていると想像するべきです。あなたが最後に到達したとき、sそれはそれが最初にあったものではありません。したがって、実際には、元の(あなたの場合)s[-2]と比較して、はるかに下にあります。sb


編集

それで、それをどのように宣言して、それが新しいサイズに動的に調整されるようにするのですか?

可能であれば、適切なサイズに調整するのは難しいです。あなたができること:

  • そのように宣言します:char b[LENGTH] = "Hello";
  • string_catサイズを指定するために別のパラメータを渡します

複数回繰り返した後、最終的にはstrncpy/のようなものになりmemcpyます。

于 2013-01-07T07:25:42.470 に答える
2

負の方向に格納されるのではなく、連結中にポインタを( *s++whileループで)インクリメントしているため、末尾は文字列の末尾を指します。ポインタのコピーを保存して、内部の文字列の先頭(必要な場合)を失わないようにすることができます。while((*s++ = *d++)!='\0');sstring_cat

コードには、スタックバッファオーバーランにつながる可能性のある他の問題があります。

char b[] = "Hello";

固定サイズのバッファです。と連結b1するbと、最終的にバッファオーバーランが発生し、UBが発生し、最終的にクラッシュする可能性があります。

于 2013-01-07T07:25:10.603 に答える