strcpyのエラーについて

このQ&Aのポイント
  • strcpyとは、文字列をコピーする関数ですが、使用時にエラーが発生することがあります。
  • エラーの原因は、ライブラリの問題やコピー文字列が大きすぎることなどが考えられます。
  • エラーを回避するには、strcpy_s関数を使用するか、_CRT_SECURE_NO_WARNINGSを使ってエラーメッセージを無効化する方法があります。
回答を見る
  • ベストアンサー

strcpyのエラー

こんばんは。 困りました、また文字列に関するエラーです。 文字列の例題でsprcpyを使おうとすると必ず出ます。 何やら調べてみるとライブラリの問題だとかコピーする文字列が大きすぎてコピー先のバッファに入らない場合これを通知する方法がないからとか色んなエラーの原因が述べられています。 エラーを出さずにビルド、コンパイルして実行するにはどのような方法が 一番良いのでしょうか? ご教示お願いします・・・。 エラーの詳細 重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー 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.

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

なぜ非推奨かというとですが・・・ strcpy(buffer,<ここにあるもの>); <ここにあるもの>が、バイトコードで0になるまでをコピーする特性と bufferの長さを見ていない特性の2つが問題で。 もし、0で終わる文字ではないものをコピーすると、bufferを 破壊して、それでも止まらずあちこちのメモリを破壊する習性がありまして。 同じ理由で0で終わる文字だったとしても、bufferが 適切な長さではない場合は、存在しないメモリ(他人のメモリ) を書き換える/破壊するなどの問題を起こすため、 こういう警告がついているという具合です。 いうなればこういう状態 char buffer[3]; strcpy(buffer,"ABC"); ABCは3文字だから大丈夫と思っていると、実は0で終わる文字なので、 ”ABC"+"\0"と、4バイト必要です。 しかし、3バイトしか確保していないので、 隣接する他のメモリを1バイト壊したよ?ってことです。

aiueo6391
質問者

お礼

回答ありがとうございます。 そういうことでしたか、理解していませんでした、申し訳ありません。 破壊・・・、気を付けないと、自分で自分のPCを破壊することになるということですよね。 とても怖いですね、気を付けます。

その他の回答 (1)

回答No.1

https://docs.microsoft.com/ja-jp/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4996?view=vs-2019 これなんですが。前回言った通り現在非推奨の関数なので、 こうなってるんですが。 同じ理由で "str"で始まるほとんどの関数が、同じワーニングになります。 strcatなども char buffer[256]; strcpy(buffer,"i am "); strcat(buffer,"people"); /* bufferの「後ろ」に文字を結合 */ printf("%s\n",buffer); など・・

aiueo6391
質問者

お礼

回答ありがとうございます。

関連するQ&A

  • Visual C++ 2008 Expreesのコンパイルについて

    夜も遅くに申し訳ありません 現在、Visual C++ ExpressでCのソースを書いているのですが 以下のような警告がでてしまいます 1>------ ビルド開始: プロジェクト: addres2, 構成: Release Win32 ------ 1>コンパイルしています... 1>strling.c 1>.\strling.c(19) : warning C4090: 'return' : 異なる 'const' 修飾子です。 1>.\strling.c(67) : warning C4090: 'return' : 異なる 'const' 修飾子です。 1>save.c 1>.\save.c(8) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\stdio.h(237) : 'fopen' の宣言を確認してください。 1>namesort.c 1>nameret.c 1>.\nameret.c(20) : warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\stdio.h(279) : 'gets' の宣言を確認してください。 1>main.c 1>.\main.c(30) : warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\stdio.h(279) : 'gets' の宣言を確認してください。 1>load.c 1>.\load.c(15) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\stdio.h(237) : 'fopen' の宣言を確認してください。 1>key.c 1>input.c 1>.\input.c(13) : warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\stdio.h(279) : 'gets' の宣言を確認してください。 1>.\input.c(28) : warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\stdio.h(279) : 'gets' の宣言を確認してください。 1>.\input.c(31) : warning C4047: '関数' : 間接参照のレベルが 'char *' と 'char (*)[64]' で異なっています。 1>.\input.c(31) : warning C4024: 'InputKey' : の型が 1 の仮引数および実引数と異なります。 1>リンクしています... 1>コード生成しています。 1>コード生成が終了しました。 1>マニフェストを埋め込んでいます... 1>ビルドログは "file://g:\プログラム\addres2\addres2\Release\BuildLog.htm" に保存されました。 1>addres2 - エラー 0、警告 10 ========== ビルド: 1 正常終了、0 失敗、0 更新不要、0 スキップ ========== 一応は正常終了するのですが実行ファイル(exe)が生成されません 原因を探そうとネットを漁ってみたのですが判らないままです。 警告を全て消さないといけないのでしょうか? 申し訳ありませんが教えてください

  • _CRT_SECURE_NO_DEPRECATE が効かない?

    お世話になっております。 現在、Windows XP、VC++2005 にてプログラム中なのですが、 「strcpy()」についてです。 本ライブラリはセキュリティ強化のため「strcpy_s()」の使用を 奨励されていますが、箇所が多いので取り合えずWarningだけでも 取りたいと思っています。 -- #include "stdafx.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { char szBuf[10]; strcpy( szBuf, "test" ); return 0; } -- というサンプルコードに対して warning C4996: 'strcpy' が古い形式として宣言されました。 'strcpy' の宣言を確認してください。 'This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.' と出たので、ファイルの先頭に #define _CRT_SECURE_NO_DEPRECATE と加えたのですがWarningが取れません。 同様に #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 としても駄目でした。 他に何か必要なことはあるのでしょうか? #pragmaは出来るだけ避けたいのですが。 以上、よろしくお願い致します。

  • scanf関数について

    質問があります。 最近C言語を勉強し始めたのですが、scanf関数を使うと以下のような警告が出ます。 「arning 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. c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(306) : 'scanf' の宣言を確認してください。」 使用しているのは Visual C++ 2008 Express Editionです。

  • c言語でエラーが出ます。

    以下のプログラムでコンパイルするとエラーが出ます。どこが間違えていますか? #include <stdio.h> int main(void) { int vx,vy; puts("二つの整数を入力して下さい。"); printf("整数vx:"); scanf("%d", &vx); printf("整数vy:"); scanf("%d", &vy); printf("vx+vy=%d\n", vx+vy); printf("vx-vy=%d\n", vx-vy); printf("vx*vy=%d\n", vx*vy); printf("vx/vy=%d\n", vx/vy); printf("vx%%vy=%d\n", vx%vy); return(0); } コンパイラーはmicrosoft visual studio 2012です。エラー表示は「error 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. 」と出ます。 8行目のscanfの文にエラーと出ますがどこが間違っているか分かりません。どなたか分かる方教えて頂けますか?

  • ライブラリ関数

    文字列をコピーする(strcpy) 文字列の長さを調べる(strlen) 配列の長さを調べる(sizeof) #include <stdio.h> #include <string.h> int main(void) { char s1[128] = "ABCD"; char s2[128] = "EFGH"; char s3[128] = "IJKL"; strcpy(s2, s1); strcpy(s3, s2); puts("s1をs2にs2をs3にコピーしました。"); printf("s1 = %s\n", s1); printf("s2 = %s\n", s2); printf("s3 = %s\n", s3); printf("文字列%sの長さは%uです。\n",s3,(unsigned)strlen(s3)); printf("文字列%sの長さは%uです。\n",s3,strlen(s3)); return (0); } char *strcpy(char *d, const char *s) { while (*d++ = *s++) printf("pointer=%s \n",d); } /* 文字列sをdにコピーする[配列版] */ char *strcpy(char d2[], const char s2[]) { unsigned i=0; while (d2[i] = s2[i]){ i++; printf("hairetsu=%s\n",&d2[i]); } } /*--- 文字列strの長さを返す[ポインタ版] ---*/ size_t strlen(const char *s) { size_t len = 0; while (*s++) len++; return (len); } /*--- 文字列strの長さを返す[配列版] ---*/ unsigned strlen(const char str[]) { unsigned len = 0; while (str[len]) len++; return (len); } c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の宣言を確認してください。 メッセージ: 'This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.' c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の宣言を確認してください。 メッセージ: 'This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.' c:\documents and settings\owner\my documents\visual studio 2005\projects\test8-3\test8-3\test8-3.c(48) : error C2084: 関数 'char *strcpy(char *,const char *)' は既に本体を持っています。 c:\program files\microsoft visual studio 8\vc\include\string.h(73) : 'strcpy' の前の定義を確認してください c:\documents and settings\owner\my documents\visual studio 2005\projects\test8-3\test8-3\test8-3.c(68) : error C2084: 関数 'size_t strlen(const char *)' は既に本体を持っています。 c:\program files\microsoft visual studio 8\vc\include\string.h(80) : 'strlen' の前の定義を確認してください 上記の問題が解決できません。助けてください><

  • ファイルから入力した文字数をカウントして出力する。

    ファイルから入力した文字数をカウントしてファイルに出力するプログラムをVC++のC言語を使ってビルドしたのですが警告が出ます。 何処が拙いのでしょうか? 教えて下さい。 実行環境はOSがWindows Vistaで統合開発環境がVisual C++ 2008です。 C言語初心者なので分かりやすく教えて下さい。 /* count_char.c */ #include <stdio.h> #include <stdlib.h> /* for exit(); */ int main(int argc, char *argv[]) { FILE *fin, *fout; int len; int ch; char ss[80]; if (argc != 3) { printf("引数の数が違います、エラー。用法:count_char fromfile tofile\n"); exit(1); } if ((fin = fopen(argv[1], "r")) == NULL) { printf("読み込みファイル%sがオープン出来ません。\n", argv[1]); exit(1); } if ((fout = fopen(argv[2], "w")) == NULL) { printf("書き込みファイル%sがオープン出来ません。\n", argv[2]); exit(1); } len = 0; while ((ch = fgetc(fin)) != EOF) { len++; } sprintf(ss, "文字数=%d\n", len); fputs(ss, fout); fclose(fin); fclose(fout); return 0; } 警告の内容は以下の通りです。 1>------ ビルド開始: プロジェクト: count_char, 構成: Debug Win32 ------ 1>コンパイルしています... 1>count_char.c 1>c:\vc9\count_char\count_char\count_char.c(16) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : 'fopen' の宣言を確認してください。 1>c:\vc9\count_char\count_char\count_char.c(20) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : 'fopen' の宣言を確認してください。 1>c:\vc9\count_char\count_char\count_char.c(30) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(366) : 'sprintf' の宣言を確認してください。 1>マニフェストをリソースにコンパイルしています... 1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0 1>Copyright (C) Micros

  • DirectX / C++の外部読み込みについて

    #include"DxLib.h" #define SIZE(27) #define size(300) #define PI_H(10) #define PI_W(10) int MyDrawPixel(int x, int y, int color){ int sx, sy, Wh=GetColor(255,255,255), Bl=GetColor(0,0,0); int col[]={Wh,Bk}; : : DrawBox(sx, sy, sx+SIZE-1, sy+SIZE-1, col[color],TURE);return0; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE PrevInstance,LPSTR lpCmdLine,int nCmdShow){ int SetFontThickness(int TinckPal), CheckHitKey (int KeyCode),MouseX, MouseY; int i,j,PixelData[PI_H][PI_W]; FILE *fp; fp=fopen("p.txt","r"); if(fp==NULL){printfDx("FILE ERORR");exit(0);} for(i=0; i<PI_H; i++){ for(j=0; j<PI_W; j++){ scanf("%d", &PixelData[i][j]); } } fclose(fp); : : : } とファイルを読み込ませましたが、warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : 'fopen' の宣言を確認してください。 warning 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. 1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(306) : 'scanf' の宣言を確認してください。 と表示されます。 原因を探していますが、解決方法はあるのでしょうか?

  • strcpyについて

    下記のコードはpの容量が分からないのにstrcpy()を実行しています。 #include <iostream.h> int main() { char *p = "a"; strcpy(p,"bbbbbbbbbbbbbbb"); cout << p; return 0; } エラーにならなかったのですが、このコードはこれでいいんですか? この場合、strcpy()の第2引数は相当長い文字列へのポインタでも大丈夫なんですか?

  • _tfopen について教えてください

    ファイルリストを作成するソフトを作っています。VC++2010 ユニコードの設定で コーディングしています。 韓国語を含むファイル名を出力しようとすると、韓国語以降の文字が処理されず、 仕様を変えました。 仕様変更後、リストコントロール上のアイテム(ファイル情報)をユニコードで入出力するのはうまくいっています。 しかし、警告が出て気分が悪いので、(コンパイルは通ります。)、この際推奨される記述を したいです。 _wsetlocale(LC_ALL, _T("jpn"));も記述しています。 目的は、入力の時は、1行ずつ読込みたいです。なるべくソースの骨格を変えずに修正したいです。 問題の箇所は、   int err = 0;   CString rstr;   CStdioFile stdFile(_tfopen(importFilePath, _T("r, ccs=UNICODE")));  //←警告がでる   while (!err) {     if (stdFile.ReadString(rstr) == FALSE) err = 1;       ~処理~   }    //(6)クローズ(明示的)   stdFile.Close();   _wsetlocale(LC_ALL, _T(""));   return 1; 警告内容: 警告  3  warning C4996: '_wfopen': This function or variable may be unsafe. Consider using _wfopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.  D:\Visual Studio 2010 - Data\Projects\FileListCreator_UNICODE_import_export(79)\FileListCreator\FileListCreatorDlg.cpp  2600 元のコードは以下のサイトを参考に作りました。 http://www.g-ishihara.com/mfc_fi_02.htm できれば… CStdioFile stdFile を残して、なんとかしたいです。 教えてくださるとうれしいです。

  • 自作のstrcpyもどきがきちんと動作しません

    自作のstrcpyもどきがきちんと動作しません この前から、strcpyもどきを作っているのですがうまく動作しません。 strcpyもどきは 第一引数のバッファに第二引数の書式にしたがって、%sがあるところに第三引数の文字列を入れるという動作させるつもりです。 例として、 書式: TEST%%%sAIUEO 文字列: AB 希望する結果: TEST%ABAIUEO としてみたのですが、バッファの中身を見ると、ところどころTESTやAIUEOとあるのですが、変なデータが入ってしまうようで、 for文でバッファの中身をすべて0にしてみると、%から後が表示されなくなりました。 長文で申し訳ありませんが、ご教示よろしくお願いします. 呼び出し元 --------------------------------------------------- int main (){ char strbuf[50]; char str[]="AB"; strPaste(strbuf, "TEST%%%sAIUEO", str); printf("%s\n", strbuf); return 0; } 本体 --------------------------------------------------- int strPaste (char *buf, const char *format, const char *str){ int i,j,k, cflag; for(i=0, j=0, cflag=0; format[i] != 0; i++, j++){ if(cflag == 1){ if(format[i] == '%') buf[j] = '%'; if(format[i] == 's'){ for(k=0; str[k] != 0; k++, j++) buf[j] = str[k]; } cflag=0; continue; } if(format[i] == '%') cflag = 1; else buf[j] = format[i]; } return 0; }