Меню

Strncpy c выдает ошибку

25 / 23 / 2

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

Сообщений: 88

1

30.06.2011, 21:42. Показов 11693. Ответов 6


Решил после сдачи курсовой, для себя сделать курсовую до конца, и брать не честно стыренную у соседа по парте, и переделать, а написать свою. И всё бы хорошо, но вот столкнулся с проблемой…
Перерыл весь гугл, но до меня так и не дошло…
Решил сделать несколько языков в программе, для теста делаю отдельно, и вот собственно сама проблема:

warning C4996: ‘strcpy‘: This function or variable may be unsafe.

Гугл перерыл, нашел несколько решений, но не помогают…
Может кто объяснить в чём моя ошибка?

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
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
 
using namespace std;
 
enum {HeadProg};
enum {MsgMenuOne=1, msgMenuTwo, MsgMenuThree};
enum {MsgErrorOne=4, MsgErroTwo};
enum {MsgEndProg=6};
 
char msg[30][150];
 
bool massage_prog();
 
int main ()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    If(massage_prog()) return 0;
    cout<<msg[HeadProg]<<endl;
    cout<<msg[MsgMenuOne]<<endl;
    cout<<msg[MsgErrorOne]<<endl;
    return 0;   
}
 
bool massage_prog() 
{   
    int otv, flag=1;
    char imf[10];
    while (flag){
        cout<<"Выберите язык:n1 - русскийn2-украинскийn";
        cin>>otv;
        switch (otv) {
        case 1: strcpy(imf,"msg_ru.txt");
                    flag=0;
                    break;
        case 2: strcpy(imf,"msg_ua.txt");
                    flag=0;
                    break;
            default:cout<<"nНеверно задан кодn";
                        system ("cls");
        }
    }
    ifstream msg_in(imf);
    if(msg_in.fail()) {     
cout<<"nОшибка открытия файлаnn";
return 1;
}
    int i=0;
    while (!msg_in.eof()) { 
        msg_in.getline(msg[i],80);
        i++;
    }
    msg_in.close();
    return 0;
}

Для чего такое построение с функциями? enum улетит в хедер файл, massage_prog() в отдельный cpp файл, main () — в главный файл программы.

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



0



    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,0672 ]   [ 16 queries used ]   [ Generated: 29.01.23, 02:08 GMT ]  

                            • Forum
                            • General C++ Programming
                            • Strncpy Error

                            Strncpy Error

                            Im receiving a error C4996 and says it is unsafe to use «strncpy», how can I fix this?

                            If you are using Visual Studio you can #define _CRT_SECURE_NO_WARNINGS before your #include files.

                            Not recommended. It is using a bomb to swat a fly. And doesn’t fix the problems with the functions, you can still have buffer overruns.

                            OR

                            Use C11’s strncpy_s() function that was created to prevent buffer overruns.

                            See TheIdeasMan’s link for how to use.

                            At the design level, while the above answers tell you how to use strncpy safely, you might consider not using it at all. If you can, just use a C++ string type instead.

                            strncpy isn’t unsafe as it’s bounded by the buffer size of the input and/or the string length of the input.

                            Last edited on

                            That strncpy is unsafe and deprecated is Microsoft’s own opinion, it still part of C and C++ standard.
                            The suggested alternative strncpy_s is only supported on Visual Studio and C11.

                            IMHO people who like safety shouldn’t use C or C++ at all.

                            Topic archived. No new replies allowed.

                            See more:

                            When I use «strncpy» I had the error:
                            «Error C4996 ‘strncpy‘: This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.»

                            and when I try ‘strncpy_s‘ I had the error:
                            «Error (active) E0304 no instance of overloaded function «strncpy_s» matches the argument list»

                            What I have tried:

                            #include <stdio.h>  
                            #include <stdlib.h>  
                            #include <string.h>  
                            #include <crtdbg.h>  // For _CrtSetReportMode  
                            #include <errno.h> 
                            bool GetWord(char* theString,
                            	char* word, int& wordOffset);
                            
                            // driver program
                            int main()
                            {
                            	const int bufferSize = 255;
                            	char buffer[bufferSize + 1]; // hold the entire string
                            	char word[bufferSize + 1]; // hold the word
                            	int wordOffset = 0; // start at the beginning
                            
                            	std::cout << "Enter a string : ";
                            	std::cin.getline(buffer, bufferSize);
                            
                            	while (GetWord(buffer, word, wordOffset))
                            	{
                            		std::cout << "Got this word: " << word << std::endl;
                            	}
                            	return 0;
                            }
                            
                            // function to parse words from a string.
                            bool GetWord(char* theString, char* word, int& wordOffset)
                            {
                            	if (theString[wordOffset] == 0) // end of string?
                            		return false;
                            
                            	char *p1, *p2;
                            	p1 = p2 = theString + wordOffset; // point to the next word
                            
                            									  // eat leading spaces
                            	for (int i = 0; i<(int)strlen(p1) && !isalnum(p1[0]); i++)
                            		p1++;
                            
                            	// see if you have a word
                            	if (!isalnum(p1[0]))
                            		return false;
                            
                            	// p1 now points to start of next word
                            	// point p2 there as well
                            	p2 = p1;
                            
                            	// march p2 to end of word
                            	while (isalnum(p2[0]))
                            		p2++;
                            
                            	// p2 is now at end of word
                            	// p1 is at beginning of word
                            	// length of word is the difference
                            	int len = int(p2 - p1);
                            
                            	// copy the word into the buffer
                            	strncpy(word, p1, len);
                            
                            
                            	// null terminate it
                            	word[len] = '';
                            
                            	// now find the beginning of the next word
                            	for (int j = int(p2 - theString); j<(int)strlen(theString)
                            		&& !isalnum(p2[0]); j++)
                            	{
                            		p2++;
                            	}
                            
                            	wordOffset = int(p2 - theString);
                            
                            	return true;
                            }


                            Solution 2

                            The are 2 possible solutions:
                            1. Add _CRT_SECURE_NO_WARNINGS to your project’s settings and use strncpy();
                            2. Use

                            strncpy_s(word, p1, len);

                            Comments

                            Solution 3

                            strncpy[^] and strncpy_s[^] have different signatures, namely strncpy_s needs the size of the destination string as additional parameter. Hence you would have to call it this way

                            strncpy(word, word_size, p1, len);

                            (and you would have to change GetWord signature accordingly, in order to pass word_size).

                            Another option is ignoring or suppressing the warning.

                            Comments

                            Solution 1

                            This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

                             

                            Print

                            Answers RSS

                            Top Experts
                            Last 24hrs This month

                            CodeProject,
                            20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8
                            +1 (416) 849-8900

                            0 0 голоса
                            Рейтинг статьи
                            Подписаться
                            Уведомить о
                            guest

                            0 комментариев
                            Старые
                            Новые Популярные
                            Межтекстовые Отзывы
                            Посмотреть все комментарии

                            А вот еще интересные материалы:

                          • Яшка сломя голову остановился исправьте ошибки
                          • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
                          • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
                          • String subscript out of range c ошибка
                          • Stop bremsen fehler betriebs anleitung ошибка