55726


ここに投稿自体初めてで不足等あった場合すいません。エラーになる理由を教えていただけますでしょうか。

[code]

    #include "pch.h"
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    
    int main(void)
    {
        char str[10];
        **strcpy (str, "MARIO");**
        printf("%s\n", str);
        return 0;
    }
    
[/code]

返信ありがとうございます。エラーは以下のように出ました。

**エラーメッセージ**

[code]

    C4996 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead.
    To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    ConsoleApplication4 c:\users\takuy\source\repos\consoleapplication4\consoleapplication4.cpp 12
    
[/code]

最初は文字の打ち間違いと思いましたが参考書通りに入力したためそれも違い、何をまちがっているのか分からなくなってしまいました。


CC BY-SA 4.0
2019-06-12T10:36:10.843
55721
2019-06-14T01:03:15.630
2019-06-12T13:27:00.453
7291
34680
question
c visual-c++
C言語の文字列コピーをvisual studioで実行するとstrcpyの部分がエラーになってしまいます。


それは、使用している参考書が古くて、今では使わない方が良い関数が使われているからです。

**strcpy()をstrcpy_s()に置き換える** か(ただしパラメータや戻り値が違うので、参考書の記述からは外れます)、
**コンパイラの警告レベルを下げて、かつ_CRT_SECURE_NO_WARNINGSを#defineしてエラーや警告が出ないようにする**
か(ただしそれに慣れるとエラーや警告を見落としたり無視することになります)、などの対策が考えられます。

参考書は、なるべく初版が最近のものか、VisualStudioXXXXの新しい版に対応しているというものを選びましょう。  
初心者ということで、これからも色々エラーに遭遇するでしょうが、分からないならば、この辺をやってみれば良いでしょう。

エラーメッセージをWeb翻訳にかけてみる：

> この関数や変数は安全ではないかもしれません。 代わりにstrcpy_sを使用することを検討してください。  
>  非推奨を無効にするには、_CRT_SECURE_NO_WARNINGSを使用してください。 詳細についてはオンラインヘルプを参照してください。

エラーコード(今回はC4996)で検索する：  
[コンパイラの警告 (レベル 3) C4996](https://docs.microsoft.com/ja-jp/cpp/error-
messages/compiler-warnings/compiler-warning-level-3-c4996?view=vs-2019)  
[安全でない CRT ライブラリ関数](https://docs.microsoft.com/ja-jp/cpp/error-
messages/compiler-warnings/compiler-warning-level-3-c4996?view=vs-2019#unsafe-
crt-library-functions)

> この関数または変数が安全なない可能性があります。使用を検討して safe_version 代わりにします。非推奨を無効にするには、
> _CRT_SECURE_いいえ_警告します。詳しくは、オンライン ヘルプをご覧ください。  
>  Microsoft には、いくつかの CRT と C++ 標準ライブラリの関数とより安全なバージョンを優先してグローバルは非推奨とされます。
> ほとんどの場合では、非推奨の関数は、未チェックの読み取りまたは重大なセキュリティ問題につながる、バッファーへの書き込みアクセスを許可します。
> コンパイラは、これらの関数は使用されなくなったとの警告を発し、優先関数を提案します。  
>  この問題を解決するをお勧め関数または変数を使用するsafe_version代わりにします。
> バッファーの上書きのことはできませんまたは移植性のためのコードを変更することはできません overread
> して、コードで発生することを確認した場合は、警告をオフにできます。  
>  CRT のこれらの関数の警告をオフにするには、次のように定義します。 _CRT_SECURE_いいえ_警告します。
> 非推奨のグローバル変数に関する警告をオフにするには、次のように定義します。 _CRT_SECURE_いいえ_警告_GLOBALSします。
> これらの非推奨の関数とグローバル変数の詳細については、次を参照してください。 CRT のセキュリティ機能と安全なライブラリ。C++
> 標準ライブラリします。

他には、直接の対策では無いですが、MicrosoftのDocsサイトの解説を検索・閲覧して理解するようにしてみてください。

* * *

ちなみに、C言語やその規格の変遷の概要は以下にまとまっています。  
[C言語 - Wikipedia](https://ja.wikipedia.org/wiki/C%E8%A8%80%E8%AA%9E)

言語自身の規格の変遷と、コンパイラのベンダー/版数による対応の差が合わさり、参考書が何を前提に書かれているかに依って、出来ることが使わない方が良くなったり、出来ないことが出来るようになったりして、変わってきています。

このスタックオーバーフローのサイトでも、先人の初心者さんが、それらにハマっていっぱい質問してたりするので、それを検索することでも勉強になるでしょう。


CC BY-SA 4.0
2019-06-12T12:10:02.550
55726
2019-06-12T14:17:15.007
2019-06-12T14:17:15.007
26370
26370
55721
answer


結論としてはVisual Studioに対応した参考書を参照されることをお勧めします。  
kunifさんの回答と被りますが、時系列に整理します。

* * *

[C4996](https://docs.microsoft.com/ja-jp/cpp/error-messages/compiler-
warnings/compiler-warning-
level-3-c4996?view=vs-2019)（[英語](https://docs.microsoft.com/en-us/cpp/error-
messages/compiler-warnings/compiler-warning-level-3-c4996?view=vs-2019)）は

> コンパイラの警告 (レベル 3)

とあるようにあくまで警告です。今回の場合、Visual Studio
2005で導入された[CRTのセキュリティ機能](https://docs.microsoft.com/ja-jp/cpp/c-runtime-
library/security-features-in-the-
crt?view=vs-2019)及び[CRT関数のセキュリティが強化されたバージョン](https://docs.microsoft.com/ja-
jp/cpp/c-runtime-library/security-enhanced-versions-of-crt-
functions?view=vs-2019)によって警告が出力されています。具体的には

>
> たとえば、`strcpy`関数には、コピーする文字列が大きすぎてコピー先のバッファーに入らない場合、これを通知する方法がありません。ただし、セキュリティで保護されたバージョンの`strcpy_s`では、バッファーのサイズをパラメーターとして取り、バッファーオーバーランが発生するかどうかを事前に判断できます。`strcpy_s`を使用して、11文字を10文字バッファーにコピーしようとすると、これはエラーになります。`strcpy_s`でこの間違いを訂正することはできませんが、このエラーを検出して、無効なパラメーター
> ハンドラーを呼び出すことにより、エラーの発生を通知できます。

と説明されている通りで、開発者の記述したソースコード通りに正常に動作する実行ファイルが生成されます。

次になぜエラーとなるかですが、Visaul Studio 2012でコンパイルオプション[/sdl (追加のセキュリティ
チェックの有効化)](https://docs.microsoft.com/ja-jp/cpp/build/reference/sdl-enable-
additional-security-checks?view=vs-2019)（[英語](https://docs.microsoft.com/en-
us/cpp/build/reference/sdl-enable-additional-security-
checks?view=vs-2019)）が導入されました。セキュリティ上の脅威となり得るため、C4996を含むいくつかの警告はエラーとして扱います。ただし、この機能は明示的に有効化しなければ、引き続き警告のままです。

更にVisual
Studio2017ではプロジェクトファイル作成ウィザードに/sdlを有効化するチェックボックスを用意し、既定でチェックをつけました。明示的にチェックを外すか、後からプロジェクトの設定を変更することで無効化できます。またこれはあくまでプロジェクト設定であり、コンパイラー本体は引き続き既定で警告として扱います。

更にVisual Studio
2019ではプロジェクトファイル作成時に既定で/sdlを有効化しました。チェックボックスは廃止されましたが、後からプロジェクトの設定を変更することで無効化できます。コンパイラー本体は既定で警告として扱います。

* * *

こういったセキュリティ強化の変遷がありますので、参照された参考書がVisual
Studioに対応していなかったり、対応していても古い場合には、エラーとなってしまいます。

一時的な対策としては、上記の`/sdl`追加のセキュリティチェックを無効化することです。ただし、セキュリティ上の脅威となるため無効化するのではなく、最新のVisual
Studioに対応した参考書で学習されることをお勧めします。


CC BY-SA 4.0
2019-06-12T21:09:54.017
55731
2019-06-14T01:03:15.630
2019-06-14T01:03:15.630
4236
4236
55721
answer