scanf_s関数には バッファオーバーフローを防ぐため入力文字数制限機能が付けられています

scanf_s関数には バッファオーバーフローを防ぐため入力文字数制限機能が付けられています



アレサ「再びですが


scanf関数をつかって配列に文字列をとりこむために


配列宣言

char hairetu[100];

おこなって

配列変数を

100個用意したとします


ここでは


プログラムの入力、実行に


統合開発環境Visual Studioをつかってみましょう。


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void) {

char hairetu[100];

printf("文字列を入力してください\n");

scanf("%s", hairetu);


printf("%s", hairetu);


return 0;

}


Visual Studioの場合


プログラムの実行結果


文字列を入力してください

パズルでやっほう(と入力すると)

パズルでやっほう


この場合


char hairetu[100];


により生成される配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[98]

hairetu[99]


には99個の文字データと


文字列であることをコンピュータに認識させるナル文字データ'\0'


を格納することができるので


8文字の文字列

👇

パズルでやっほう

(平仮名は2バイト文字なので 文字列データ"パズルでやっほう"は16個の文字データ プラス ナル文字データ'\0'の17個の文字データに相当します)


は余裕をもって


格納することができます


では


100文字以上の文字を入力した場合どうなるでしょうか?


ためしてみましょう。


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void) {

char hairetu[100];

printf("文字を入力してください\n");

scanf("%s", hairetu);


printf("%s", hairetu);


return 0;

}


プログラムの実行結果

文字を入力してください

パズルでやっほう~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(と入力すると)

パズルでやっほう~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


なんだか


統合開発環境Visual Studioでは


他社のコンパイラと比べて


かなり多くの文字列データを


scanf関数をつかってメモリに格納


printf出力表示することができています。



このとき

統合開発環境Visual Studioでは


警告文で


stack around the variable 'hairetu' was corrupted.


と表示されます


配列hairetuの周りのメモリのデータが破壊されたという意味ですね


このプログラムの実行結果をみてもわかるように


配列char hairetu[100]で生成される


配列変数(つまりメモリ)には


99個の文字データと


99個の文字データが文字列データであることをコンピュータに認識させるナル文字データ'\0'


しか格納できないのですが


それよりも多くの文字データが


コンピュータのメモリに格納され


printf出力表示ができています


このとき用意した配列char hairetu[100]に入りきなかった文字データ


は自動的に


周りのメモリに格納されていたデータに


上書きされて格納されています。


この状態を


バッファオーバーフローとよびます


バッファとはデータが1時的に保存されるメモリのことを表しています


ですから


配列変数の周りに重要なデータがあるときは


困ってしまいますの。


ですから


マイクロソフト社が独自に開発した


scanf_s関数には


入力する文字列を制限する機能が付けられています


scanf_s関数は


scanf_s("%s",hairetu,5);


のような書式が用いられます。


このscanf_s関数の第3引数が


コマンドプロンプト画面から入力できる文字列の長さを制限しています。


このscanf_s関数の第3引数に5と記述された場合は


ナル文字データ'\0'が自動的にhairetuに格納されるので


4文字までの文字列データを配列hairetuに格納することができます。


もし

4文字を超える文字列を入力すると


1文字も配列にデータが格納されないように設定されており


プログラムを実行しても


コマンドプロント画面には何も表示されません。


セキュリテイ機能が強化されているため


scanf_s関数を使って




scanf関数を使って文字列を配列hairetuに格納するとき


scanf("%s",hairetu);


と記述したように


第3引数を記述せず


scanf_s("%s",hairetu);


のように記述することはできません


必ず入力文字数を制限する第3引数の記述が必要になってきます



このような仕組みとなっているため


scanf_s関数を用いて入力文字数制限機能をつかえば


コマンドプロンプト画面から入力される文字がながすぎるため


配列変数の周りのメモリにデータがかきこまれる


周りのメモリに格納されているデータが


バッファオーバーフローにより


破壊される


ということがないというわけですね。」






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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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