見出し画像

(答案提出)C言語教室 第6回 - 文字列操作

私は最近、kznさんの記事に夢中!

前回の第5回の答案では痛恨のバグを出してしまい、リベンジに燃えています。(嘘です)

課題

・文字列のコピーする関数を書いてください。
・文字列を連結する関数を書いてください。

配列の変数名を引き数として関数を呼び出すと、呼び出された関数の側ではポインタを受け取ることになるので、元の配列を変更できることは覚えていますか?

https://note.com/kazushinakamura/n/neca9e57f426f


私の答案 - 文字列をコピーする関数

/* main.c */ 

#include <stdio.h>

void copyText(char* x, char* y) {

  while ((*y++ = *x++) != '\0')
  ;

}

void main() {
  char s1[] = "abcdefg";
  char s2[8];
  
  char *p = s1;
  char *q = s2;
 
  copyText(p, q);

  printf("s1:%s\n", s1);
  printf("s2:%s\n", s2);

}

課題の中にヒントを書いて下さっているので、直ぐに意図されておられるであろうことは判ったのですが、、、

この構文の場合、while文のあと、*y = '\0';は不要では無いかと思うんですが如何でしょうか?

私の理解が正しければ、'\0'までコピーした後でwhile文を抜けることになるのですが。


実行結果 - 文字列をコピーする関数

s1:abcdefg
s2:abcdefg

どうでしょうか? 
一応は、機能しているようです。
(動作環境;https://9cguide.appspot.com/web_picoc_em.html )


この調子で次にいってみましょう。

私の答案 - 文字列を連結する関数

/* main.c */ 
#include <stdio.h>

void concatText(char* x, char* y, char* z) {
//Copy x to z
  while ( *x != '\0' ) *z++ = *x++;

//Copy y to z  
  while ( *y != '\0' ) *z++ = *y++;

//add '\0' to z
  *z = '\0';

}

void main() {
  char s1[] = "abcdefg";
  char s2[] = "hijklmn";
  char s3[15];
  char *p = s1;
  char *q = s2;
  char *r = s3;

  concatText(p, q, r);

  printf("s1:%s\n", s1);
  printf("s2:%s\n", s2);
  printf("concat:%s\n", s3);
}


実行結果 - 文字列を連結する関数

s1:abcdefg
s2:hijklmn
concat:abcdefghijklmn

どうでしょうか? 
一応は、機能しているようです。
(動作環境;https://9cguide.appspot.com/web_picoc_em.html )


コメント

前回の反省を踏まえて、様々なデータを与えて動作検証したのですが、気になって仕方がないことがあります。

私の答案では、7文字の文字列を2つ連結して、最後に'\0'を追加して15のサイズの文字配列にセットしていますが、例えば、合計15文字以上となるようなデータを与えても、文字列の途中でロストすることなく与えた全ての文字が連結されて表示されます。

s1:abcdefg123
s2:hijklmn123
concat:abcdefg123hijklmn123

これって、プログラマの意図を超えてメモリ領域を壊してませんかね?
多分、こういう事態をハンドルするための機能がC言語にはあったような気がするのですが、、、ひょっとしてこれは次回以降の講習の伏線ですかね?


答え合わせが楽しみです!

*この記事は、私こと、Akio van der Meerが、kznさんの記事にインスパイアされて、私の責任の下で作成したものです。


追記(2022.12.02)

今回も、kznさんから答案に対するコメントをいただきました。
kznさん、ご指導有難うございました。

次回第7回は、御子息の試験等々で再来週になるそうです。
気になっていたメモリ管理についての言及があるそうなので、とても楽しみなのですが、私も今週末から年末年始までバタバタなので、課題に取り組むことは難しそうです。合間を見つけてトライはしますが、、、。(言い訳)


ここまで読んでいただいて、有難うございました。

これまでの収益は全て、それを必要としておられる方々へ、支援機関を通して寄付させていただきました。この活動は今後も継続したいと思っています。引き続きよろしくお願いいたします。