Visual StudioでC言語のscanf関数を利用したら,C4996エラーが発生してビルドが失敗したんだけど...
こういった悩みにお答えします.
本記事の信頼性
- リアルタイムシステムの研究歴12年.
- 東大教員の時に,英語でOS(Linuxカーネル)の授業.
- 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
- プログラミング歴15年以上,習得している言語: C/C++,Python,Solidity/Vyper,Java,Ruby,Go,Rust,D,HTML/CSS/JS/PHP,MATLAB,Assembler (x64,ARM).
- 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」をGitHubにオープンソースとして公開.
- 2020年1月~現在はアメリカのノースカロライナ州チャペルヒルにあるGuarantee Happiness LLCのCTOとしてECサイト開発やWeb/SNSマーケティングの業務.2022年6月~現在はアメリカのノースカロライナ州チャペルヒルにあるJapanese Tar Heel, Inc.のCEO兼CTO.
- 最近は自然言語処理AIとイーサリアムに関する有益な情報発信に従事.
- (AI全般を含む)自然言語処理AIの論文の日本語訳や,AIチャットボット(ChatGPT,Auto-GPT,Gemini(旧Bard)など)の記事を50本以上執筆.アメリカのサンフランシスコ(広義のシリコンバレー)の会社でプロンプトエンジニア・マネージャー・Quality Assurance(QA)の業務委託の経験あり.
- (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を200本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.
こういった私から学べます.
C言語を独学で習得することは難しいです.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!
目次
C言語のC4996エラー
C言語のC4996エラーとは,Visual Studioで安全ではない標準ライブラリ関数を利用する際,ビルド時に発生するエラーです.
※C4996エラーは正確には警告ですが,便宜上エラーとして扱います.
C4996エラーが発生する標準ライブラリ関数として,scanf関数が挙げられます.
scanf関数を利用するコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { int i; printf("Please input an integer: "); scanf("%d", &i); printf("i = %d\n", i); return 0; } |
Visual Studioでビルドすると,12行目のscanf関数でC4996エラーが発生します.
代替方法として以下が記載されています.
- scanf_s関数の利用
- _CRT_SECURE_NO_WARNINGSをプリプロセッサでマクロ定義
1 2 3 4 |
エラー C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. |
Visual StudioでC4996エラーを回避する4つの方法
Visual StudioでC4996エラーを回避する4つの方法を紹介します.
- プロパティのSDLチェックで無効
- プリプロセッサで無効
- 他のC言語の関数で代替
- C++言語のクラスや関数で代替
C4996エラーをプロパティのSDLチェックで無効に設定
Visual Studio 2012からSecurity Development Lifecycle(SDL)チェックという機能が追加されたことで,C4996は警告からエラーに格上げされています.
C4996エラーをプロパティのSDLチェックで無効に設定するためには,以下の手順を行って下さい.
設定が正常に完了するとC4996がエラーから警告に変更されますので,再度ビルドすると成功します.
実行結果は以下になります.正常に実行できました.
※他の方法の実行結果も同じなので,以降は省略します.
1 2 3 4 5 |
Please input an integer: 123 i = 123 *.exe (プロセス *) は、コード 0 で終了 しました。 このウィンドウを閉じるには、任意のキーを押してください... |
C4996エラーをプリプロセッサで無効に設定
C4996エラーをプリプロセッサで無効に設定する「ファイル全体」と「ファイルの一部」の2つの方法を紹介します.
ファイル全体でC4996エラーを無効に設定
ファイル全体でC4996エラーを無効に設定するためには,以下のプリプロセッサのどちらかを書きます.
1 |
#define _CRT_SECURE_NO_WARNINGS |
1 |
#pragma warning(disable:4996) |
_CRT_SECURE_NO_WARNINGSは,ファイルの先頭(stdio.h等のヘッダのインクルード前)で定義する必要があります.
これに対して,warning(disable:4996)はscanf関数等の呼び出し前で良いので,stdio.h等のヘッダのインクルード後でも可能ですが,ファイルの先頭に書いた方が無難です.
上記のプリプロセッサをファイルの先頭に書いた各々のコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main(void) { int i; printf("Please input an integer: "); scanf("%d", &i); printf("i = %d\n", i); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #pragma warning(disable:4996) #include <stdio.h> int main(void) { int i; printf("Please input an integer: "); scanf("%d", &i); printf("i = %d\n", i); return 0; } |
ファイルの一部を無効
ファイルの一部だけC4996エラーを無効に設定するためには,以下のようなプリプロセッサを書きます.
そして,C4996を無効にしたい行の前後をDISABLE_C4996とENABLE_C4996で挟みます.
1 2 3 4 5 6 7 |
#ifdef _MSC_VER #define DISABLE_C4996 __pragma(warning(push)) __pragma(warning(disable:4996)) #define ENABLE_C4996 __pragma(warning(pop)) #else #define DISABLE_C4996 #define ENABLE_C4996 #endif |
上記のプリプロセッサを利用するコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #ifdef _MSC_VER #define DISABLE_C4996 __pragma(warning(push)) __pragma(warning(disable:4996)) #define ENABLE_C4996 __pragma(warning(pop)) #else #define DISABLE_C4996 #define ENABLE_C4996 #endif #include <stdio.h> int main(void) { int i; printf("Please input an integer: "); DISABLE_C4996 scanf("%d", &i); ENABLE_C4996 printf("i = %d\n", i); return 0; } |
C4996エラーが発生しない他のC言語の関数で代替
C4996エラーが発生しない他のC言語の関数で代替します.
scanf関数の代替はscanf_s関数ですので,12行目をscanf_s関数の呼び出しに変更します.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { int i; printf("Please input an integer: "); scanf_s("%d", &i); printf("i = %d\n", i); return 0; } |
他のC4996エラーが発生する関数は,「MSC24-C. の非推奨関数や時代遅れの関数」で推奨されている関数で代替できます.
参考:C++言語のクラスや関数で代替
Visual StudioのコンパイラはC/C++言語用なので,C言語の機能や関数のみで実装するという制約がなければ,C++言語のクラスや関数で代替できます.
C言語のscanf関数をC++言語の標準入力ストリームstd::cin(std::istreamクラスのオブジェクト)で代替するコードは以下になります.
※printf関数も標準出力ストリームstd::cout(std::ostreamクラスのオブジェクト)で代替しています.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <iostream> int main(void) { int i; std::cout << "Please input an integer: "; std::cin >> i; std::cout << "i = " << i << std::endl; return 0; } |
まとめ
Visual StudioでC言語のC4996エラーを回避する4つの方法を紹介しました.
scanf関数を例にして,SDLチェックで無効に設定,プリプロセッサで無効に設定,他のC言語の関数で代替,C++言語のクラスや関数で代替する方法を解説しました.
C言語を独学で習得することは難しいです.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!