strcat_s関数はつなげた文字列データが配列に入りきらない場合は文字列データを配列に格納しません

ソーラー「まずは


strcat関数が用いられたプログラムをご覧ください

👇


Visual Studioをお使いの方は


strcat_sをお使いください


もしくは

プログラムの冒頭で


#pragma warning(disable: 4996)

を記述してください


#pragma warning(disable: 4996)

#include <stdio.h>

#include <string.h>//🌞ヘッダファイル<string.h>をインクルードしてください


int main(void){

char hairetu1[100]="nekoneko";

char hairetu2[100]="lalala";

strcat(hairetu1, hairetu2);


printf("%s\n",hairetu1);

return 0;

}


Visual Studioの場合


ビルド実行結果


nekonekolalala



EAZY IDECの場合

コンパイル結果


nekonekolalala


ソーラー「


strcat(hairetu1, hairetu2);


が実行されると


配列hairetu1に格納された文字列データ"nekoneko"



配列hairetu2に格納された文字列データ"lalala"


がつなげられた文字列データ"nekonekolalala"



配列hairetu1に格納されることになります


ここで


もし

char hairetu1[100]="nekoneko";

でなく

char hairetu1[10]="nekoneko";


が実行されていたなら


10個の配列変数しかもたない配列hairetu1に


ナル文字¥0を含めた15個の文字データにより形成される文字列データ"nekonekolalala"


が格納されることになります


その場合


配列hairetu1に格納しきれなかったデータは


周りのメモリに格納されているデータに上書きされて格納されることになります


もし

strcat


の代わりに


strcat_s関数をつかって


strcat_s(hairetu1, hairetu2);


が実行されると


strcat_s関数のセキュリティ機能がはたらいて


配列hairetu1には何も文字データが格納されないことになります


そのことを示すプログラムは次のようになります

👇


#pragma warning(disable: 4996)

#include <stdio.h>

#include <string.h>//🌞ヘッダファイル<string.h>をインクルードしてください


int main(void) {

char hairetu1[10] = "nekoneko";

char hairetu2[100] = "lalala";

strcat_s(hairetu1, hairetu2);


printf("%s\n", hairetu1);

return 0;

}


ビルド実行結果


何も表示されません


同時に以下の警告文が表示されます


Debug Error!

Program:

C:\Users\solarplexuss\source\repos\Project33\Debug\Project33.exe

Module:

C:\Users\solarplexuss\source\repos\Project33\Debug\Project33.exe

File:


Run Time Check Failure #2 _ Stack around the vriable 'hairetu1' was corrupted.


(Press Retry to debug the application)


中止(A)  再試行(R) 無視(I)



ソーラー「どう?


strcat_s関数のセキュリティ機能が働いて


配列hairetu1には何も文字データが格納されないので


printf("%s\n", hairetu1);


の実行結果は何も表示されないんだね」





ソーラー「

さて

配列hairetu1内に格納された文字列データ"nekoneko"と

配列hairetu2内に格納された文字列lalalaをデータ"lalala"をつなげて


"nekonekolalala"と1つの文字列をつくった。よかった。


nekonekolalalaをコマンドプロンプト画面に表示するときには


printf("%s\n", hairetu1);


とhairetu1を用いるだけでいい・・・となると?」


アレサ

「配列hairetu1内の文字列データ"nekoneko"と配列hairetu2内の文字列"データ"lalala"を


strcat関数をもちいてつなげたあと


配列hairetu2には何がはいっているのですか?・・・となるなる」


ソーラー「そう!


そこで


配列hairetu1内の文字列データ"nekoneko"

配列hairetu2内の文字列データ"lalala"を


strcat関数をもちいてつなげたあと


配列hairetu2内の中身に何がはいってるかを


printf出力表示するプログラムを構成してコンパイルしてみます。


#pragma warning(disable: 4996)

#include <stdio.h>

#include <string.h>


int main(void){

char hairetu1[100]="nekoneko";

char hairetu2[100]="lalala";


strcat(hairetu1, hairetu2);


printf("%s\n",hairetu2);/*配列hairetu1内の文字列データ"nekoneko"と配列hairetu2内の文字列データ"lalala"をつなげます。その後、配列hairetu2内に何が格納されているかをprintf表示してみます*/

return 0;

}


EAZY IDECの場合

コンパイル結果


lalala


Visual Studioの場合


lalala


ソーラー「なんかいいかも


配列hairetu1と配列hairetu2内の文字列をつなげても


配列hairetu2には元から入っていた文字列データ"lalala"が残ってるってことか・・



    😸配列hairetu1に格納されている文字列データだけが😸



"nekoneko"から"lalala"に増えたというわけなんだね



では


strcat(hairetu1, hairetu2);によって


配列hairetu1に格納されている文字列データが"nekonekolalala"になったのなら



さらに


strcat(hairetu1, hairetu2);を実行して


その配列hairetu1に格納されている文字列データ"nekonekolalala"



さらに配列hairetu2に格納されている文字列データ"lalala"


をつけたしたなら


printf("%s\n",hairetu1);


の実行結果はどうなるのかな?」


アレサ「さて どうなるのでしょうか?


そのプログラムを実行してみます

👇


#pragma warning(disable: 4996)

#include <stdio.h>

#include <string.h>


int main(void) {

char hairetu1[100] = "nekoneko";

char hairetu2[100] = "lalala";

strcat(hairetu1, hairetu2);

/*まず

配列hairetu1内の文字列データ"nekoneko"と配列hairetu2内の文字列データ"lalala"をつなげます。

その結果 配列hairetu1内の文字列データは"nekonekolalala"になります*/


strcat(hairetu1, hairetu2);


/*ここで配列hairetu1内の文字列データ"nekonekolalala"に

さらに配列hairetu2内の文字列データ"lalala"をつなげます*/


printf("%s\n", hairetu1);

printf("%s\n", hairetu2);

return 0;

}


コンパイル結果(EAZY IDECの場合)


nekonekolalalalalala

lalala


Visual Studioの場合


ビルド実行結果


nekonekolalalalalala

lalala


ソーラー 「やったね,アレサ、上々の出来


配列hairetu1内に格納された文字列データが


"nekonekolalala"

から

"nekonekolalalalalala"


に増えたね


配列hairetu2内に格納された文字列データは


"lalala"


のままだね



ならば次は


strcat(hairetu1, hairetu2);


for文を使い


配列hairetu1内に格納された文字列データ"nekoneko"


配列hairetu2内に格納された文字列データ"lalala"


を10回つなげてみる。


#pragma warning(disable: 4996)

#include <stdio.h>

#include <string.h>


int main(void){

char hairetu1[100]="nekoneko";

char hairetu2[100]="lalala";


int a;

for(a=1;a<11;a++)strcat(hairetu1, hairetu2);


/*この命令文

配列hairetu1内の文字列データ"nekoneko"に

配列hairetu2内の文字列データ"lalala"を10回つなげます。


lalala~lalala~


猫🐈🐈🐈の喜びを表現しようとしています*/


printf("%s\n",hairetu1);

return 0;

}


ソーラー「


このプログラムを

エディタにうちこんでいって・・・・・・


おや、🐈🐈🐈の絵文字をうちこんだら文字化けすると思ったら・・・??


🐈の絵文字が かろうじて表現されてる???

👆ここが個人的には重要なポイントです by ソーラー


かわい~い~な この🐈の絵文字


それではプログラムをコンパイルっ」


EAZY IDECの場合

コンパイル結果


nekonekolalalalalalalalalalalalalalalalalalalalalalalalalalalalalala


Visual Studioの場合


ビルド実行結果


nekonekolalalalalalalalalalalalalalalalalalalalalalalalalalalalalala


ソーラー「これもコンパイル成功。


ではでは無限に配列hairetu2内の文字列データ"lalala"を


配列hairetu1内の文字列データ"nekoneko"につなげてみることは~~できるのかな~~


for文の条件式を

for(a=1;a<11;a++)から無限仕様の

for(;;)に変化させ

無限に

配列hairetu2内の文字列データ"lalala"を

配列hairetu1内の文字列データ"nekoneko"につなげるプログラムを作製してみると~~~」



#pragma warning(disable: 4996)



#include <stdio.h>

#include <string.h>


int main(void) {

char hairetu1[100] = "nekoneko";

char hairetu2[100] = "lalala";


int a;

for (;;)strcat(hairetu1, hairetu2);


/*この命令文

配列hairetu1内の文字列データ"nekoneko"に

配列hairetu2内の文字列データ"lalala"を10回つなげます。


lalala~lalala~


猫🐈🐈🐈の喜びを表現しようとしています*/


printf("%s\n", hairetu1);

return 0;

}



ソーラー 「このプログラムをコンパイルしてみると・・・」



コンパイル結果


_



ソーラー「コンパイル結果は _ アンダーバーのみ・・・」


アレサ「もしかすると


配列hairetu1内の文字列データ"nekoneko"に


配列hairetu2内の文字列データ"lalala"を無限に繋げ続ける・・・


配列hairetu1内に無限に文字列データ"lalala"を格納する追加して格納する・・・ということは


つまり


命令文for(;;)strcat(hairetu1, hairetu2);


は無限に実行されることになり


命令文printf("%s\n",hairetu1);


の実行までには辿り着かないのではないでしょうか?


ですので


コマンドプロンプト画面に


 プログラムの実行中を示す


 _


アンダーバーが表示されているのでは


ないですか ソーラーさん?」


ソーラー「あっそうかも」













  • Xで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る