基本的にVisual Studioではオーバーフローの起こる可能性のあるメモリにデータを格納する関数はセキュリティ機能が強化されています

scanfとscanf_sの違いとは何でしょうか?

ソーラー


「scanfとscanf_sでは何が違うのか


ここで考察してみま~す。


まずは

scanf関数を使って文字列データ"neko"を


配列hairetuに格納するプログラムが


次のように表されているとします。」


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10];

scanf("%s",hairetu);

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


return 0;

}



ソーラー「


このプログラムを実行して


アンダーバー_が表示される


入力待ち受け状態のコマンドプロンプト画面で


nekoとうちこむと


nekoがprintf出力表示されます。


ふつうじゃ~ん


とおもわれますね


ここで


char hairetu[10];


と配列の要素数が10になっています。


配列の要素数が10ということは


この配列hairetu内に生成される

char型の配列変数

hairetu[0]

hairetu[1]

hairetu[2]

hairetu[3]

hairetu[4]

hairetu[5]

hairetu[6]

hairetu[7]

hairetu[8]

hairetu[9]



には'a'や'b'という文字がナル文字'\0'を含めて


10個格納できるということになります


つまり、ナル文字'\0'と


9文字分の文字列データが格納できます


逆に言うと9文字をこえる文字列データは


配列hairetuに格納できないということです。


ならば


このプログラムで9文字以上の文字列nekonekonyannyaを


入力したなら


プログラムの実行結果は


どうなるでしょうか?」


🐤


scanf関数はそのままでは


マイクロソフト社の統合開発環境Visual Studioでは使えないので


Visual Studioをお使いの方は

プログラムの冒頭に

#pragma warning(disable: 4996)

をつけるのを忘れないでください


🐤  🐤. . .


ソーラー「


ふたたびプログラム


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10];

scanf("%s",hairetu);

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


return 0;

}


を実行して


アンダーバー_が表示される入力待ち受け状態の


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


nekonekonyannyaを入力すると・・・


nekonekonyannya(入力すると)

nekonekonyannya


なんか普通に入力そして出力できていますね


要素数は何のために設定されてるのかな?


意味ないという気がするね」


アレサ「ふつうに


9文字をこえる文字列がprintf出力表示されていますの」


ソーラー「そこで


今のscanf関数を使ったプログラム


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void)

{

char hairetu[10];

scanf("%s",hairetu);

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


return 0;

}

を実行した後


今度は


アンダーバー_が表示される


入力待ち受け状態のコマンドプロンプト画面で


nekonekonyannyanekonekonyannyanekonekonyannyanekonekonyannya

nyanyanyanyanyannyannyannyannnyanyanyanyanyannyannyannyannnekonekonyannyanekonekonyannyanekonekonyannyanekonekonyannyanyanyanyanyanyannyannyannyannnyanyanyanyanyannyannyannyannnyanyanyanyanyanyanyanyanyanyanyanyanyanyanyanyanyannyannyannyannnyanyanyanyanyannyannyannyannnekonekonyannyanekonekonyannyanekonekonyannyanekonekonyannyanyanyanyanyanyannyannyannyannnyanyanyanyanyannyannyannyannnyanyanyanyanyanyanyanyanyanyanyanya


とうちこむと


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


scanf関数は


ある1定の文字数を超える文字列を入力することはできないのです。」


アレサ「そうですの・・」


ソーラー「さあここで 


scanf_s関数に登場してもらいましょう。


scanf_s関数は


scanf_s("%s",配列名,入力できる文字数);


と記述し


コマンドプロンプト画面から


入力できる文字数を制限できる機能があります。


引数が3つあります


今のプログラムの場合では


具体的には


scanfの部分を


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


と記述することにより


コマンドプロンプト画面から入力できる文字数を


ナル文字を含めた5文字までに制限することができます。


ただし


scanf_s関数はマイクロソフト社の統合開発環境Visual Studioでしか


使えません。


以下のプログラムでは


統合開発環境Visual Studioをつかってプログラムを作製


実行しています。


さきほどのプログラムの


scanfの部分を


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


とかきかえた


次のプログラムを実行すると


#include <stdio.h>


int main(void)

{

char hairetu[10];

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

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


return 0;

}


Visual Studioの場合


ビルド実行結果


neko(4文字入力すると)

neko


となります


では

5文字nekonを入力してみるとどうなるかな?


#include <stdio.h>


int main(void)

{

char hairetu[10];

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

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


return 0;

}


Visual Studioの場合


ビルド結果


nekon(5文字入力すると)

何も表示されません


つまり


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


が実行された場合


ナル文字\0を含めて5文字まで


が配列hairetuに格納可能となります


つまり


ナル文字\0は1文字とカウントされるので


4文字までが


キーボードから入力可能となります


ですから


4文字を超える文字をキーボードから入力すると


scanf_s関数の


文字列入力制限機能のはたらきにより


コマンドプロンプト画面には何も表示されないことになります」


scanf_s「にゃはははは~~~」


アレサ

「なぜこのような文字列入力制限機能が scanf_s関数にはついているのかというと・・・」

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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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