文字列コピー 関数 strcpy

strcpy は、string.hをインクルードすれば、利用できます。
しかし正しく利用するには、その関数がどのように作られたものかを理解する必要があります。 以下では、この関数の定義例と利用例を紹介します。

char a[10];
char *s = "abc";
a = s;

文字並びを記憶可能なaの配列があり、その配列に s が管理する文字列を記憶させる場合、上記の=演算子で可能でしょうか? それは、できません!
できない理由は2つあります。 
一つめの できない理由: aは配列名で変更対象にできない。(定数と同じ取り扱い)
二つめの できない理由: sは、"abc"と記憶される領域の先頭アドレスを表現して いるだけで、仮に=の左が変更可能な対象であっても、アドレスという番地の値を代入するだけになる。

以上より、単純に=演算子で文字列記憶内容をコピーすることはできません。
そして、このような場合は、標準関数のstrcpy関数を使って、strcpy( a, s ); と実行させます。

この関数の中では、sの指し示す文字並びを、sが指し示す位置へ、 1文字ずつ=演算でコピーする処理が行なわれています。
この繰り返しは、'\0'のコードをコピーするまで行なわれます。

引数のポインタ変数を変更しない定義例

( s1[i] = s2[i] ) の1byte代入を'\0'が行なわれるまで、 iで位置をずらしながら繰り返す処理です。
なお、戻れ値は、第一引数と同じ値です。

#include <stdio.h>
char * strcpy(char *s1, char *s2)
{
	int i = 0;
	while( ( s1[i] = s2[i] ) != '\0' ){
		i++;
	}
	return s1;
}
main()
{
	char w[128]; /* 127byte分の文字を記憶できる配列 */
	char a[3][6];/* 5byte分の文字を記憶できる配列を3個用意した */
	int i;
	for(i = 0; i < 3 ; i++){
		printf("文字列入力>" , a );
		gets(w);			/* 1行入力 */
		strcpy( a[i] , w ); 	/* strcpy( & a[i][0] , w ); と書いてもよい */
	}
	for(i = 0; i < 3 ; i++){
		puts( a[i] ); 		/* puts( & a[i][0] ); と書いてもよい */
	}
}

strcpy定義を確認するため、mainで配列wへ入力し、その文字列を &a[i++][0]にコピーする繰り返しを 3回行なって、その後に表示する繰り返しを行なっています。
その実行例を以下に示します。 (なお、ここではstrcpyの戻り値を利用しませんでした。)

文字列入力>abc
文字列入力>1 234
文字列入力>wxyz
abc
1 234
wxyz

なお、この入力で6文字以上の入力を行なうと、正しい結果が得られなくなります。 つまり、それは配列の範囲を超えたアクセスになるからです。
この関数も、関数定義例からもわかるように、 コピー元の文字列が記憶可能範囲を超えるサイズであっても、コピーしようとします。
つまり、 利用する方で正しく使わなければならない関数といえます。

引数のポインタ変数を変更するstrcpy関数定義例

上記strcpyと同じ機能を行なわせる別の定義例を、以下に示します。
ここでは、添え字用変数 i を使っていません。ポインタ引数の変数を変更することで、 コピーする文字コードを記憶する位置を変更しています。
■■■■ の記述を正しく直して完成くだささい。
([]の配列演算子を使わずに、*のポインタ演算子を使ってください。ポインタ変更は後置インクリメントを使ってください)

←編集 入力後に クリックください。

このようなポインタの変数を変更する方式は、C言語独特の作り方です。 なお、極端に省略して関数を定義すると次のようになります。(分かり難いと感じる人が多いので薦めませんが・・・)

#include 
char * strcpy2(char *s1, char *s2)
{
	char * startp = s1;
	while( *s1++ = *s2++ ) ; /* 空文の繰り返し */
	return startp;
}

*s1++ = *s2++の式の結果は、 s1のポインタを増やす前のs1が指し示す記憶域への代入値です。 (この代入操作が行う以外に、s1とs2のポインタは次の位置を指すように変更されます) この代入値が0でなければ、条件判定が成立するので、文字列終端の0までコピーされます。