- ベストアンサー
strcat関数
学校の課題で strcat関数と全く同じ働きをするmy_strcatを実装せよ という課題がでています。 strcatは char* strcat(char *dest, const char *str) で表され、文字列 strを文字列 dest に合成して 合成された新しい文字列として dest を返します。 例えば、dest = Japan, str = Korea だったら, 関数処理後に、 dest = JapanKorea を戻り値とします。 ********************************************* my_strcat実装について 実装段階で一番の問題になるのが、文字列のサイズです。 とりあえず、私の書いたコードを示します↓ char* my_strcat(char *dest, const char *src) { int i=0; int j=0; while(*dest) { dest++; i++; } while(*src) { *(dest+i) = src[0]; i++; src++; } *(dest+j) = src[0]; //put null at the end of dest return dest; } 試しにdest=Japan,str=Koreaでやってみたのですが、動きませんでした。 原因はdest の文字サイズを無視した無理やりなりな実装だと考えます。 C言語では文字のサイズを一度宣言したら、変えられないと思うので、困っています。 どなたかアドバイスをいただけないでしょうか。 よろしくお願いします
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
★原因は『*(dest+j)』行の部分です。 ・間違い⇒『*(dest + j)』 正しい⇒『*(dest + i)』 分かりますか? 『j』ではなくて『i』なのです。 ・それから『j』は使っていませんよね。宣言の必要はないと思います。 また、『dest++』してポインタを移動したものをリターンしています。 これでは『dest』の末尾に『src』を追加コピーして『src』と同じ文字列の先頭を 返すことになってしまいますよ。標準ライブラリの strcat 関数と動作が異なります。 ・さらに『dest』や『src』でポインタを使っているならば、『i』カウンタは必要ない! 下に『i』カウンタを使わないでポインタでの記述を載せます。 サンプル: char* my_strcat( char *dest, const char *src ) { char *ret = dest; ←先頭位置を記憶 while ( *dest != '\0' ){ dest++; } while ( *src != '\0' ){ *dest++ = *src++; } *dest = '\0'; ←src[0]をコピーするよりも'\0'の方が分かりやすよ(コメントするよりかはね) return( ret ); ←記憶しておいた先頭位置を返す } 最後に: ・while 文の条件式で『*dest != '\0'』と記述したほうが分かりやすくなります。 ・あと回答者 No.1 さんのアドバイスどおり、合成格納領域『dest』に合成する『src』の メモリが十分にないとメモリなどを破壊します。でも、このことは標準関数の『strcat』も 同じですので『my_strcat』の実装は上記の方法のように格納領域のサイズは気にしなくても よいでしょう。→標準関数の『strcat』と同じなら。 ・以上。参考に!
その他の回答 (1)
- koko_u_
- ベストアンサー率18% (459/2509)
strcat は dest の指す位置に結合後の文字列を格納する十分な領域が確保されていることが前提です。 char dest[11] = "Japan"; と後ろに余裕を持たせましょう。
お礼
回答ありがとうございます。 変数が結合に十分なメモリ領域をもつことが前提なんですね。
お礼
回答ありがとうございます。 私のポインタの使い方がいかに悪かったかわかりました。 おかげさまでポインタについての理解が深まり、勉強になりました。 strcatの他に、strcpyなども実装する宿題なのですが、Oh-Orangeさんのおかげで、他の関数も以前よりすっきりしたコードを書くことができました。 ありがとうございます。