Strcpy c ошибка

How to fix this : Error 1 error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
  • Remove From My Forums
  • Question

  • // ptrstr.cpp -- using pointers to strings
    #include <iostream>
    #include <cstring>              // declare strlen(), strcpy()
    int main()
    {
        using namespace std;
        char animal[20] = "bear";   // animal holds bear
        const char * bird = "wren"; // bird holds address of string
        char * ps;                  // uninitialized
    
        cout << animal << " and ";  // display bear
        cout << bird << "n";       // display wren
        // cout << ps << "n";      //may display garbage, may cause a crash
    
        cout << "Enter a kind of animal: ";
        cin >> animal;              // ok if input < 20 chars
        // cin >> ps; Too horrible a blunder to try; ps doesn't
        //            point to allocated space
    
        ps = animal;                // set ps to point to string
        cout << ps << "!n";       // ok, same as using animal
        cout << "Before using strcpy():n";
        cout << animal << " at " << (int *) animal << endl;
        cout << ps << " at " << (int *) ps << endl;
    
        ps = new char[strlen(animal) + 1];  // get new storage
        strcpy_s(ps, animal);         // copy string to new storage
        cout << "After using strcpy():n";
        cout << animal << " at " << (int *) animal << endl;
        cout << ps << " at " << (int *) ps << endl;
        delete [] ps;
        cin.get();
        cin.get();
        return 0; 
    }

    How to fix this : Error 1 error C4996: ‘strcpy’: This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

    I tried using strcpy_s but the following appeared:

    Error 1 error C2660: ‘strcpy_s’ : function does not take 2 arguments c:usersalexandrosdocumentsvisual studio 2013projectslisting 4_20listing 4_20ptrstr.cpp 27 1 Listing 4_20

    2 IntelliSense: no instance of overloaded function «strcpy_s» matches the argument list
                argument types are: (char *, char [20]) c:UsersAlexandrosDocumentsVisual Studio 2013ProjectsListing 4_20Listing 4_20ptrstr.cpp 28 5 Listing 4_20

    Using VS2013 ultimate

    • Edited by

      Tuesday, August 11, 2015 12:03 PM

Answers

  • ps = new char[strlen(animal) + 1];  // get new storage
    strcpy_s(ps, sizeof(animal), animal);         // copy string to new storag

    You allocate strlen(animal) of space for the ps variable, and then in the next line of code, lie to the strcpy_s function and state that you allocated sizeof(animal) number of characters.

    • Edited by
      Brian Muth
      Tuesday, August 11, 2015 7:09 PM
    • Marked as answer by
      Shu 2017
      Monday, August 24, 2015 6:00 AM

  • Hi ClassicalGuitar,

    If you can guarantee that the destination string has enough space to hold the source string including its null-terminator, just use strcpy() and ignore the compiling warning; if the compiling warning is carking, suppress it with
    #define _CRT_SECURE_NO_WARNINGS
    or
    #pragma warning(disable : 4996)

    You may also use
    #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
    to let the compiler automatically replaces strcpy() with strcpy_s() for you. See at
    https://msdn.microsoft.com/en-us/library/ms175759.aspx

    From the MSDN document about strcpy() and strcpy_s(), the main difference between both is that, if the destination space is not enough, while strcpy() proceeds in silence, strcpy_s() calls default Invalid Parameter Handler Routine to consciously crash the
    program and make you be awared of it with a report; see at
    https://msdn.microsoft.com/en-us/library/ksazx244.aspx.

    You may overload the Invalid Parameter Handler Routine with your own function that not terminating the execution; in the case, strcpy_s() returns error; you are required to handle the program flow when the error happens.

    If the destination and source strings overlap, the behaviors of strcpy() and strcpy_s() are undefined.

    • Marked as answer by
      Shu 2017
      Monday, August 24, 2015 6:00 AM

  • Reply both to Igor Tandetnik and kwick:

    Read documentation for warning C4996

    In C++, the easiest way to do that is to use Secure Template Overloads, which in many cases will eliminate deprecation warnings by replacing calls to deprecated functions
    with calls to the new secure versions of those functions. For example, consider this deprecated call to
    strcpy:

       char szBuf[10]; 
       strcpy(szBuf, "test"); // warning: deprecated 
    

    Defining _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES as 1 eliminates the warning by changing the
    strcpy call to strcpy_s, which prevents buffer overruns. For more information, see
    Secure Template Overloads.

    The template overloads provide additional choices. Defining _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES to 1 enables template overloads of standard CRT functions that call the more secure variants automatically. If
    _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES is 1, then no changes to the code are necessary. Behind the scenes, the call to
    strcpy will be changed to a call to strcpy_s with the size argument supplied automatically.

    It is better for me to use a #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

    Now code becomes:

    // ptrstr.cpp -- using pointers to strings
    #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
    #include <iostream>
    #include <cstring>              // declare strlen(), strcpy()
    int main()
    {
        using namespace std;
        char animal[20] = "bear";   // animal holds bear
        const char * bird = "wren"; // bird holds address of string
        char * ps;                  // uninitialized
    
        cout << animal << " and ";  // display bear
        cout << bird << "n";       // display wren
        // cout << ps << "n";      //may display garbage, may cause a crash
    
        cout << "Enter a kind of animal: ";
        cin >> animal;              // ok if input < 20 chars
        // cin >> ps; Too horrible a blunder to try; ps doesn't
        //            point to allocated space
    
        ps = animal;                // set ps to point to string
        cout << ps << "!n";       // ok, same as using animal
        cout << "Before using strcpy():n";
        cout << animal << " at " << (int *) animal << endl;
        cout << ps << " at " << (int *) ps << endl;
    
        ps = new char[strlen(animal) + 1];  // get new storage
        strcpy(ps, animal);         // copy string to new storage
        cout << "After using strcpy():n";
        cout << animal << " at " << (int *) animal << endl;
        cout << ps << " at " << (int *) ps << endl;
        delete [] ps;
        cin.get();
        cin.get();
        return 0; 
    }
    

    and compiles and run without errors.

    This issue is solved!

    • Marked as answer by
      ClassicalGuitar
      Friday, August 28, 2015 5:27 PM

tst

1 / 1 / 0

Регистрация: 23.08.2015

Сообщений: 216

1

03.12.2015, 00:05. Показов 5177. Ответов 12

Метки нет (Все метки)


Добрый вечер. В строке 24 появляется ошибка: error C4996: ‘strcpy’: This function or variable may be unsafe.

Предлагает использовать взамен strcpy_s — пробую, но тогда пишет, что эта функция не принимает два аргумента.
Подскажите, как быть в данном случае?

C++
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//P6-05.CPP - макросредства для перменного списка параметров
 
#include<iostream> 
using namespace std;
#include<locale>
#include<sstream>  // Для работы со строками
#include<stdarg.h>  // Для макросредств
#include<cstdlib>  // Для функции malloc()
 
char *concat(char *s1, ...)
 
{
    va_list par;  // Указатель на параметры списка
    char *cp = s1;
    int len = strlen(s1); // Длина 1-го параметра
    va_start(par, s1); // Начало переменного списка
    // Цикл для определения общей длины параметров-строк:
    while (cp = va_arg(par, char *))
 
        len += strlen(cp); // Выделение памяти для результата:
    char *stroka = (char *)malloc(len + 1);
    strcpy(stroka, s1);
    va_start(par, s1);   // Начало переменного списка
    // Цикл конкатенации параметров строк:
    while (cp = va_arg(par, char *))
        strcat(stroka, cp); // Конкатенация двух строк
    va_end(par);
    return stroka;
    
}
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    char* concat(char* s1, ...); // Прототип функции
    char* s;                     // Указатель для результата
    s = concat("nNulla ", "Dies ", "Sine ", "Linea!", NULL);
    s = concat(s, " - Ни одного дня без черточки!", "nt",
        "(Плиний Старший о художнике Апеллесе)", NULL);
    cout << s;
 
    cin.get();
    return 0;
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



QVO

652 / 462 / 80

Регистрация: 26.10.2010

Сообщений: 1,263

Записей в блоге: 4

03.12.2015, 00:40

2

tst, вместо strcpy используйте strcpy_s

C++
1
strcpy_s(stroka, len, s1);



1



1 / 1 / 0

Регистрация: 23.08.2015

Сообщений: 216

03.12.2015, 00:49

 [ТС]

3

Помогло

Подскажите, а чтобы перейти от strcat к strcat_s какой параметр нужно будет дописать? Так как теперь тоже ошибку выдает



0



652 / 462 / 80

Регистрация: 26.10.2010

Сообщений: 1,263

Записей в блоге: 4

03.12.2015, 01:04

4



1



1 / 1 / 0

Регистрация: 23.08.2015

Сообщений: 216

03.12.2015, 01:25

 [ТС]

5

Получается, что там должна быть длина, т.е. len?



0



7275 / 6220 / 2833

Регистрация: 14.04.2014

Сообщений: 26,871

03.12.2015, 09:57

6

Отключи SDL в свойствах проекта и пользуйся обычной функцией.



1



Kerry_Jr

Эксперт PHP

3102 / 2587 / 1219

Регистрация: 14.05.2014

Сообщений: 7,231

Записей в блоге: 1

03.12.2015, 10:05

7

tst, а еще смой первой строкой файла можно сделать эту

C++
1
#define _CRT_SECURE_NO_WARNINGS



1



7275 / 6220 / 2833

Регистрация: 14.04.2014

Сообщений: 26,871

03.12.2015, 10:11

8

Kerry_Jr, нет, нужно в свойствах проекта. Это строка сама по себе не поможет.



0



Эксперт PHP

3102 / 2587 / 1219

Регистрация: 14.05.2014

Сообщений: 7,231

Записей в блоге: 1

03.12.2015, 14:09

9

nmcf, всем помогает, а ему не поможет?



0



1 / 1 / 0

Регистрация: 23.08.2015

Сообщений: 216

03.12.2015, 15:01

 [ТС]

10

Мне тоже помогло. Еще попробовала вот эту — сработало:

#pragma warning(disable : 4996)
А если все-таки с strcat_s — есть какая-то сложность с определением этого параметра?



0



7275 / 6220 / 2833

Регистрация: 14.04.2014

Сообщений: 26,871

03.12.2015, 16:12

11

Эта строка убирает предупреждения, насколько я помню. Хотя они не мешают компилировать. А вот когда не компилируется, надо в свойства проекта.

Добавлено через 2 минуты

Цитата
Сообщение от tst
Посмотреть сообщение

strcat_s

Там три параметра, а не 2 как у нормальной strcat().



1



1 / 1 / 0

Регистрация: 23.08.2015

Сообщений: 216

03.12.2015, 16:20

 [ТС]

12

Да, это понятно. Хотелось бы понять, где взять этот третий параметр в данном случае



0



7275 / 6220 / 2833

Регистрация: 14.04.2014

Сообщений: 26,871

03.12.2015, 16:28

13

Второй параметр — размер строки-приёмника. Если ты её объявлял, значит, знаешь размер.



1



    msm.ru

    Нравится ресурс?

    Помоги проекту!

    >
    Strcpy и strncpy не робит…

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему

      


    Сообщ.
    #1

    ,
    01.07.09, 07:37

      вот что за фигня у меня высвечивается? я в одной программе всё также сделал и всё пошло, а в этой уже ошибка… пишет: warning C4996: ‘strncpy’: This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
      я же вроди бы правильно её использую: strcpy(label , «none»);
      вот к примеру..


      KILLER



      Сообщ.
      #2

      ,
      01.07.09, 07:46

        Цитата Potroshitell @ 01.07.09, 07:37

        warning C4996: ‘strncpy‘: This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

        Цитата Potroshitell @ 01.07.09, 07:37

        я же вроди бы правильно её использую: strcpy(label , «none»);

        У тебя ведь в описании ворнинга все написано!!!
        Во первых strcpy не проверяет размер буфера куда копирует, и длину строки откуда копирует, и может произойти переполнение буфера…
        Но судя по твоему ворнингу ты юзаешь strncpy она также небезопасна, т.к. не гарантируеться что она добавит в конец строки », если его небыло в исходной, вот тебе компилятор и говорит, что ты можешь юзать либо безопасную версию этой функции strncpy_s, либо залести в настройки и отрубить этот варнинг командой _CRT_SECURE_NO_WARNINGS, если тебе нужно юзать именно функцию strncpy и ворнинг мозолит глаза…


        popsa



        Сообщ.
        #3

        ,
        01.07.09, 07:47

          используй strcpy_s, strncpy_s!
          а вообще из текста варнинга все понятно ;)


          Potroshitell



          Сообщ.
          #4

          ,
          01.07.09, 07:50

            всё правильно говоришь) я об этом тоже знаю, и просто я этот пример привёл неудачный)) на самом деле у меня вот как там дело то обстоит:

            ExpandedWrap disabled

              // в заголовочном файле label обьявлен как указатель на char…

              label = new char[20];

              strncpy(label , s2 , 19);

              label[19] = »;

              // ну и что компилятору тут не нравится?


            Urich



            Сообщ.
            #5

            ,
            01.07.09, 07:53

              Senior Member

              ****

              Рейтинг (т): 20

              Potroshitell
              #pragma warning(disable:4996)


              KILLER



              Сообщ.
              #6

              ,
              01.07.09, 07:57

                Цитата Potroshitell @ 01.07.09, 07:50

                // ну и что компилятору тут не нравится?

                ему все нравиться, он тебя просто предупреждает о том что использование strncpy может привести к проблемам, и даже приводит тебе пару выходов из этой ситуации, как ты поступишь дело твое, можешь отрубить этот ворнинг а можешь заменить свои две строчки:

                Цитата Potroshitell @ 01.07.09, 07:50

                ExpandedWrap disabled

                  strncpy(label , s2 , 19);

                  label[19] = »;

                одной:

                ExpandedWrap disabled

                  strncpy_s(label, s2, 20);


                Potroshitell



                Сообщ.
                #7

                ,
                01.07.09, 08:01

                  ок) хорошо, я с этим разобрался ;)
                  но вот ещё 1 проблема… он думает что обьект класса это указатель, хотя на самом деле это не так

                  ExpandedWrap disabled

                    void Bravo (const Cd & obj);

                    int main()

                    {

                    Classic c2(«Fantasia in C» , «Alfred Brendel» , 2 , 57.17 , «Philips»);

                    Bravo(c2);

                    }

                    void Bravo (const Cd & obj)

                    {

                    }

                  я кажется знаю в чём тут проблема… но как её решить? Classic наследует Cd, всмысле Cd базовый класс… поидее он должен преобразовывать Classic в Cd в функции Bravo… но почему то он этого не делает… может из-за того, что я забыл обьявить конструктор копирования?
                  вот что пишет: error C2243: приведение типов: преобразование «Classic *» в «const Cd &» существует, но недоступно

                  Сообщение отредактировано: Potroshitell — 01.07.09, 08:06


                  KILLER



                  Сообщ.
                  #8

                  ,
                  01.07.09, 08:10

                    Цитата Potroshitell @ 01.07.09, 08:01

                    Classic наследует Cd, всмысле Cd базовый класс… поидее он должен преобразовывать Classic в Cd в функции Bravo… но почему то он этого не делает…

                    Чего то ты недоговариваешь, кусок кода где эти классы объявлены и используються покажи, и откуда у тебя взялсо «Classic *»


                    Potroshitell



                    Сообщ.
                    #9

                    ,
                    01.07.09, 08:14

                      ExpandedWrap disabled

                        // classic.h

                        #ifndef _CLASSIC_H_

                        #define _CLASSIC_H_

                        #include «cd.h»

                        class Classic : Cd

                        {

                        private:

                            char zadacha[40];

                        public:

                            Classic(char * s1, char * s2, int n, double x, char * zad);

                            Classic();

                            virtual void report() const;

                            virtual ~Classic();

                        };

                        #endif

                      ExpandedWrap disabled

                        // реализация классика

                        #include <iostream>

                        using namespace std;

                        #include <cstring>

                        #include «cd.h»

                        #include «Classic.h»

                        Classic::Classic(char * s1, char * s2, int n, double x, char * zad) : Cd(s1, s2, n, x)

                        {

                            strncpy(zadacha ,zad, 39);

                            zadacha[39] = »;

                        }

                        Classic::Classic() : Cd()

                        {

                            strcpy(zadacha, «none»);

                        }

                        Classic::~Classic() { }

                        void Classic::report() const

                        {

                            Cd::report();

                            cout << » Zadacha = » << zadacha << endl;

                        }

                      а базовый класс нужен?


                      Мяут



                      Сообщ.
                      #10

                      ,
                      01.07.09, 08:14

                        Преобразовываться ничего и никогда не должно. :)
                        Если у тебя есть несколько наследников от одного базового, то передавай по указателю, а в самой функции либо идентифицируй объект, либо работай только с базовой составляющей, если этого достаточно.

                        ExpandedWrap disabled

                          class A {

                              public:

                                  void foo() const;

                          };

                          class B : public A {

                              public:

                                  void bar() const;

                          };

                          void g(const A* a) {

                              B* b;

                              a->foo();

                              if(b = dynamic_cast<B*>(a)) {

                                  b->bar();

                              }

                          }


                        Potroshitell



                        Сообщ.
                        #11

                        ,
                        01.07.09, 08:18

                          тьфу блин!!! :D ппц я тупанул)) я в class Classic : public Cd, забыл слово public)) теперь всё норм работает) спс вам)


                          KILLER



                          Сообщ.
                          #12

                          ,
                          01.07.09, 08:18

                            дык…

                            Цитата Potroshitell @ 01.07.09, 08:14

                            class Classic : Cd

                            Ты юзаешь закрытое наследование, напиши так:

                            ExpandedWrap disabled

                              class Classic : public Cd

                              {

                              };

                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                            0 пользователей:

                            • Предыдущая тема
                            • C/C++: Общие вопросы
                            • Следующая тема

                            Рейтинг@Mail.ru

                            [ Script execution time: 0,0543 ]   [ 16 queries used ]   [ Generated: 10.02.23, 03:19 GMT ]  

                            Понравилась статья? Поделить с друзьями:
                          • Stop 0x000000a windows 7 при загрузке как исправить
                          • Stray ошибка при запуске
                          • Stop 0x0000009f windows 7 как исправить
                          • Stray ошибка the following components are required to run this program
                          • Stop 0x0000009c windows 7 при загрузке как исправить