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);
の実行までには辿り着かないのではないでしょうか?
ですので
コマンドプロンプト画面に
プログラムの実行中を示す
_
アンダーバーが表示されているのでは
ないですか ソーラーさん?」
ソーラー「あっそうかも」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます