24章 文字列キタコレ
http://www.geocities.jp/ky_webid/c/024.html
文字列の話です。
冒頭の文章がこれです。
これまで意図的に文字列に関する説明を省いてきました。実はC言語の文字列は、「文字の配列」として実現されています。だから「配列」を知るまでは説明を省いていたのです。更に、文字列を正しく理解するには、もう1つの考え方を理解する必要があります。それらが初心者には非常に難解なのです。
何だか出鼻を挫く様な恐ろしい文章です。理解できるかな・・・。
です。文字列の末尾には、自動的に'\0'という文字が付加されるので、80文字まで使いたいのならば要素数は81にしなければなりません。
ふむふむ文字列の終端は'\0'で表されるということですね。
ここからは難解なので、今はまだ理解できなくて構いませんが、配列の名前だけを書いた場合、それは「配列の先頭要素のアドレス」という意味になります。「アドレス」とは「そのデータがメモリ上のどこに記憶されているかを表す番号」で、住所のようなものです。C言語の学習で最難関と言われるポインタという概念と深く関係しています。一見単純そうな「文字列」というものが、最難関の概念と関わっているのです。だからこそ、完全な説明を避け続けているのです。ポインタについては、第28章以後で解説します。そのときまで、完全な意味での文字列の解説は避けます。
と・・・とりあえずここはスルーですな。
あとはstring.hの関数が紹介されています。
- strcpy
- strlen
- strcat
- strcmp
きちんと仕様を理解しておきましょう。
問題1
次のプログラムの実行結果はどうなるでしょう?
#include <stdio.h> #include <string.h> int main(void){ char str[] = "abc\0def"; printf( "%d\n", strlen(str) ); return 0; }
strlenは'\0'までを数える仕様なので出力結果は「3」のはずです。
答え合わせ
大正解!
問題2
50文字以内の2つの文字列を入力させ、それを連結したものを表示させるプログラムを作って下さい。
strcatを使う問題ですね。やってみましょう。
int main () { // 要素は'\0'の分一つ多めに char array1[21]; char array2[11]; scanf("%10s",array1); scanf("%10s",array2); strcat(array1,array2); printf("%s",array1); return 0; }
問題文では50文字以内となっていましたが、境界値のチェックのため10文字以内の制限に変えて実装してます。
$ main abc def abcdef $ main 1234567890 asdfghjkla 1234567890asdfghjkla $ main 1234567890 asdfghjklasdfghjkl 1234567890asdfghjkla
うまくいってますね。エラーも出てません。
10文字以上入力した場合もちゃんと20文字で切られて表示されています。
問題3
次の2つの文字列を交換するプログラムを作って下さい。
char str1[6] = "abcde"; char str2[6] = "edcba";
これは前回の問題と同じですね。
int main () { char str1[6] = "abcde"; char str2[6] = "edcba"; char tmp; int i; for(i=0;i<5;++i){ tmp = str1[i]; str1[i] = str2[i]; str2[i] = tmp; } printf("str1 = %s\n",str1); printf("str2 = %s\n",str2); return 0; }
まったく同じような実装になりましたね。
また、strcpyを使った場合の実装もやっておきましょう。
int main () { char str1[6] = "abcde"; char str2[6] = "edcba"; char tmp[6]; strcpy(tmp,str1); strcpy(str1,str2); strcpy(str2,tmp); printf("str1 = %s\n",str1); printf("str2 = %s\n",str2); return 0; }
strcpy使った方が簡素で良いですねー。完璧っす!