文字列を連結するプログラムを作ってみましょう。
まず、枠組みを作成します。
<sample program 085-00>
#include <stdio.h> #define MAX_STRING 10 int main(void) { char str1[MAX_STRING] = "ABC"; char str2[MAX_STRING] = "DEF"; /* このに処理プログラムを追加 */ printf("str1 = %s\n", str1); return 0; } |
<実行結果>
str1 = ABCDEF 続行するには何かキーを押してください・・・
連結というのは、ある文字列の後ろに別の文字列をくっつける、ということです。
上の実行結果を見るとstr1の後ろにstr2の文字列をくっつけているのがわかります。
連結後も文字数の最大値を超えてはならないため、"ABC"、"DEF"と短めの文字列を初期値として入れました。
コピーの応用で出来ますので、挑戦してください。
変数などは追加してもらって構いません。
くれぐれもヌル文字の存在をお忘れなく。
※思いつかない人のために、下にヒントを書いておきます。
ヒントです。
まず、図で説明してからプログラムについて書きましょう。
と言うよりは、思いつかない人はまず図から書きましょう。
str1 0 1 2 3 4 5 6 7 8 9 +−+−+−+−+−+−+−+−+−+−+ | A| B| C|\0|\0|\0|\0|\0|\0|\0| +−+−+−+−+−+−+−+−+−+−+ str2 0 1 2 3 4 5 6 7 8 9 +−+−+−+−+−+−+−+−+−+−+ | D| E| F|\0|\0|\0|\0|\0|\0|\0| +−+−+−+−+−+−+−+−+−+−+
※初期値が設定されている配列の空いている箇所(この場合は添え字の4以降)には0(ゼロ:文字で表すとヌル文字)が入る。
これを見ると、str1の3番目からstr2を連結すれば良さそうです。
str1 0 1 2 3 4 5 6 7 8 9 +−+−+−+−+−+−+−+−+−+−+ | A| B| C|\0|\0|\0|\0|\0|\0|\0| +−+−+−+−+−+−+−+−+−+−+ ↑ str2 0 1 2 3 4 5 6 7 8 9 +−+−+−+−+−+−+−+−+−+−+ | D| E| F|\0|\0|\0|\0|\0|\0|\0| +−+−+−+−+−+−+−+−+−+−+
このようなイメージですね。
文字列のコピーは、繰り返しを使って1文字ずつコピーしなければなりません。
str1[3] ← str2[0] str1[4] ← str2[1] str1[5] ← str2[2]
str1の添え字は3から始まっていますが、str2の添え字は0から始まっています。
当然ですが、str1の文字列の後ろに、str2の先頭から文字列をコピーしなければなりませんので、2つの配列の添え字は異なります。
添え字として使う変数が2つなければ出来ないことが分かります。
str1の添え字が3から、という箇所も文字列の長さを求めるプログラムを作りましたから大丈夫ですよね。
では作ってみてください。
解答例です。
<sample program 085-01>
#include <stdio.h> #define MAX_STRING 10 int main(void) { char str1[MAX_STRING] = "ABC"; char str2[MAX_STRING] = "DEF"; int i; int j; for (i = 0; str1[i] != '\0'; i++) ; for (j = 0; str2[j] != '\0'; j++) { str1[i] = str2[j]; i++; } str1[i] = '\0'; printf("str1 = %s\n", str1); return 0; } |
<実行結果>
str1 = ABCDEF 続行するには何かキーを押してください・・・
まず、最初のfor文で文字数をカウントしています。
文字数はヌル文字のある場所を表すことは前に書きました。
次のfor文で、文字のコピーを行っていますが、str1とstr2では添え字を変えています。
コピー元のstr2>でヌル文字が発見されたら繰り返しを抜けます。
str1の末尾にヌル文字を入れて終わりです。
ヒントの図を見ると、元々配列の後ろの方にはヌル文字が入っていましたが、
str1[i] = '\0'; |
は、きちんと書いています。
今回のプログラムに限れば、書かなくても動作しますが、scanfで入力した場合は配列の後ろの方は不定値になる可能性もあります。
ですから、ちゃんとヌル文字を入れるプログラムは書かなければなりません。
では、コピーと連結を組み合わせたプログラムを作ってみましょう。
次の枠組みを元に、プログラムを完成させてください。
<sample program 085-02>
#include <stdio.h> #define MAX_STRING 10 int main(void) { char str1[MAX_STRING]; char str2[MAX_STRING]; char str3[MAX_STRING * 2]; int i; int j; scanf("%s", str1); scanf("%s", str2); /* ここにプログラムを追加する */ printf("str3 = %s\n", str3); return 0; } |
<実行結果>
ABC ← str1への入力 DEF ← str2への入力 str3 = ABCDEF 続行するには何かキーを押してください・・・
str1とstr2に文字列を入力し、str3にまとめて表示するプログラムです。
str3はstr1やstr2の倍の大きさにしました。
これまでの知識で出来ますので、作ってみてください。
解答例です。
<sample program 085-03>
#include <stdio.h> #define MAX_STRING 10 int main(void) { char str1[MAX_STRING]; char str2[MAX_STRING]; char str3[MAX_STRING * 2]; int i; int j; scanf("%s", str1); scanf("%s", str2); for (i = 0; str1[i] != '\0'; i++) { str3[i] = str1[i]; } for (j = 0; str2[j] != '\0'; j++) { str3[i] = str2[j]; i++; } str3[i] = '\0'; printf("str3 = %s\n", str3); return 0; } |
<実行結果>
ABC ← str1への入力 DEF ← str2への入力 str3 = ABCDEF 続行するには何かキーを押してください・・・
str3にstr1をコピーした後に、str3にstr2を連結しました。
「文字」を扱うプログラムの時にctype.hをインクルードすることで、文字操作用の命令(関数)が使えました。
「文字列」でも同じように文字列操作用の命令(関数)がありますので、次で紹介します。