Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Компилятор выдает ошибку, помогите)))), проблема с функцией strcpy() 
:(
    Опции темы
lllJollyRogerlll
Дата 20.11.2014, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 20.11.2014

Репутация: нет
Всего: нет



Пытаюсь изучить ООП на базе С++(с помощью книги Б. Джонса и Д. Либерти), работаю с M Visual Studio, 2013, но есть и 2008. Раньше все было идеально, но вот недавно столкнулся с такой проблемой: при использовании функций strcpy() и strncpy() выдает вот такую ошибку:

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. See online help for details.    c:\users\глеб\documents\visual studio 2013\projects\consoleapplication6\consoleapplication6\source.cpp    20

и при чем оба компилятора. Что делать? Вроде все делаю как нужно, по книге код воспроизвожу, все одно и то же.




И еще, если кому не лень, пробегитесь глазами, скажите что не так: 

#include <iostream>
#include <string.h>


class String
{
public:
    //конструкторы/деструкторы
    String();
    String(const char *const);
    String(const String &);
    ~String();

    //операторы
    char & operator[] (unsigned short offset);
    char operator[] (unsigned short offset) const;
    String operator+(const String&);
    void operator+=(const String&);
    String & operator=(const String&);

    //методы доступа
    unsigned short GetLen() const { return itsLen; }
    const char* GetString() const { return itsString; }

private:
    unsigned short itsLen;
    char * itsString;
    String(unsigned short);

};

String::String(unsigned short len)
{
    itsLen = len;
    itsString = new char[itsLen];
    for (int i = 0; i <= itsLen; i++)
        itsString[i] = '\0';
}

String::String()
{
    itsLen = 0;
    itsString = new char[1];
    itsString[1] = '\0';
}

String::String(const char * const pStr)
{
    itsLen = strlen(pStr);
    itsString = new char[itsLen+1];
    for (int i = 0; i < itsLen; i++)
    {
        itsString[i] = pStr[i];
    }
    itsString[itsLen] = '\0';
}

String::String(const String & rStr)
{
    itsLen = rStr.GetLen();
    itsString = new char[itsLen + 1];
    for (int i = 0; i < itsLen; i++)
    {
        itsString[i] = rStr[i];
    }
}

String::~String()
{
    delete[] itsString;
}

char & String::operator[] (unsigned short offset)
{
    if (itsLen < offset)
        return itsString[itsLen - 1];
    else
        return itsString[offset];
}

char String::operator[] (unsigned short offset) const
{
    if (itsLen < offset)
        return itsString[itsLen - 1];
    else
        return itsString[offset];
}

String String::operator+(const String & rStr)
{
    unsigned short totalLen = itsLen + rStr.GetLen();
    String temp(totalLen);
    int i=0;
    for (i; i < itsLen; i++)
        temp[i] = itsString[i];
    for (int j = 0; j < rStr.GetLen(); i++, j++)
        temp[i] = rStr[j];
    temp[totalLen] = '\0';
    return temp;
}

void String::operator+=(const String & rStr)
{
    unsigned short totalLen = itsLen + rStr.GetLen();
    String temp(totalLen);
    int i = 0;
    for (i; i < itsLen; i++)
        temp[i] = itsString[i];
    for (int j = 0; j < rStr.GetLen(); i++, j++)
        temp[i] = rStr[j];
    delete[] itsString;
    *this = temp;
}

String & String::operator=(const String & rStr)
{
    if (this == &rStr)
        return *this;
    delete[] itsString;
    itsLen = rStr.GetLen();
    itsString = new char[itsLen];
    for (int i = 0; i < itsLen; i++)
        itsString[i] = rStr[i];
    itsString[itsLen] = '\0';
    return *this;
}


int main()
{
    String s1("initial test");
    String s2("test initial");
    s1 += s2;
    std::cout << s1.GetString();
    
    return 0;
}


Автор книги объясняет работу со строками и как бы создает калеку вот подобную) Идею я думаю вы поняли.. А я вник, понял смысл и спустя какое то время просто хотел воспроизвести что запомнилось.. Вот пробую этот класс использовать, а компилятор матерится уже после компиляции(всплывает окошко). Но саму ошибку в коде не показывает.. ( Что не так? 
Только основной вопрос вверху, это так - дополнительный, если кто поможет буду благодарен, но главное помогите с функцией strcpy() разобраться.
Всем огромное спасибо, кто уделил мне свое драгоценное время!
PM MAIL   Вверх
sQu1rr
Дата 20.11.2014, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Это не ошибка, это предупреждение, которое впринципе достаточно понятно говорит, что strcpy небезопасна (так как может привести к переполению буфера - она не проверяет границы), и советует использовать strcpy_s вместо нее. Вы можете это предупреждение проигнорировать вот так, если мне не изменяет память
Код

#define _CRT_SECURE_NO_WARNINGS


А лучше, воспользуйтесь советом и используйте strcpy_s, указывая границу:
Код

// вместо
strcpy( foo, bar );
// пишите
strcpy_s( foo, 10, bar ); // где 10 - это максимальная длина строки на перезапись


Посмотрел ваш код, во первых в следующий раз вставляйте его в тег код, а во вторых, в коде вы не используете strcpy, откуда же берется ошибка? - Понял, код к первому вопросу не относится. Может кто другой посмотрит тогда, сейчас нету компилятора под рукой

Это сообщение отредактировал(а) sQu1rr - 20.11.2014, 18:08
PM MAIL Skype GTalk   Вверх
lllJollyRogerlll
Дата 20.11.2014, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 20.11.2014

Репутация: нет
Всего: нет



Вы меня уж извините, я тут новичок, еще не знаю что и как тут..
А код это отдельный вопрос. Спасибо вам большое.
PM MAIL   Вверх
sQu1rr
Дата 20.11.2014, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(lllJollyRogerlll @  20.11.2014,  18:48 Найти цитируемый пост)
еще не знаю что и как тут

http://forum.vingrad.ru/forum/topic-48015.html пункт А)
PM MAIL Skype GTalk   Вверх
baldina
Дата 20.11.2014, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(sQu1rr @  20.11.2014,  18:05 Найти цитируемый пост)
Это не ошибка, это предупреждение

Цитата(lllJollyRogerlll @  20.11.2014,  17:38 Найти цитируемый пост)
Error    1    error C4996: 'strcpy': This function or variable may be unsafe. 


PM MAIL   Вверх
sQu1rr
Дата 20.11.2014, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Ну мы же не упражняемся в дословном переводе с английского, господин baldina
Я к тому что это не "ошибка", а компилятор мелкомягких просто хочет ограничить переполнение буфера.

http://stackoverflow.com/questions/2187304...fe-when-complin
Цитата

This is not an error, it is a warning from your Microsoft compiler.

PM MAIL Skype GTalk   Вверх
baldina
Дата 21.11.2014, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(lllJollyRogerlll @  20.11.2014,  17:38 Найти цитируемый пост)
    String operator+(const String&);
    void operator+=(const String&);

лучше сделать operator+ свободной функцией, и реализовать его через operator+= (который должен возвращать строку)
тогда код оператора будет всегда согласован (если вы захотите внести в него изменения), и появится возможность писать
Код

String a =...;
String b = "abc" + a;
String c = a+= b;


используя operator+=() не требуется доступ к приватным членам
Код

class String {
  ...
  String &operator+=(const String&);
  ...
};
String operator+(const String& lhs, const string& rhs) {
  return String(lhs) += rhs;
}

Цитата(lllJollyRogerlll @  20.11.2014,  17:38 Найти цитируемый пост)
 unsigned short itsLen;

для всяких размеров лучше использовать size_t

Цитата(lllJollyRogerlll @  20.11.2014,  17:38 Найти цитируемый пост)
String::String(unsigned short len)
{
    itsLen = len;
    itsString = new char[itsLen];
    for (int i = 0; i <= itsLen; i++)
        itsString[i] = '\0';
}

зачем строку нулями забивать?

Цитата(lllJollyRogerlll @  20.11.2014,  17:38 Найти цитируемый пост)
String::String(const char * const pStr)
{
    itsLen = strlen(pStr);
    itsString = new char[itsLen+1];
    for (int i = 0; i < itsLen; i++)
    {
        itsString[i] = pStr[i];
    }
    itsString[itsLen] = '\0';
}

вместо циклов копирования можно использовать функцию std::copy (объявлена в <algorithm>)
отдельно записывать 0 нет необходимости, его можно скопировать из исходной строки
Код

String::String(const char * const pStr)
{
    itsLen = strlen(pStr);
    itsString = new char[itsLen+1];
    std::copy (pStr, pStr+itsLen+1, itsString);
}

Цитата(lllJollyRogerlll @  20.11.2014,  17:38 Найти цитируемый пост)
String & String::operator=(const String & rStr)

operator= и конструктор копирования делают почти одно и то же. подумайте, как избежать дублирования кода

Добавлено через 6 минут и 11 секунд
Цитата(sQu1rr @  20.11.2014,  23:42 Найти цитируемый пост)
Я к тому что это не "ошибка"

да это вообще не ошибка (скорее, это не соответствие VC++ стандарту). я, кстати, удивлен, т.к. в 10 студии (а другой нет под рукой) это таки warning
но человек сказал, что не может откомпилировать, и приводит текст где видно что это ошибка. предупреждение ему не помешало бы получить результат.

Добавлено через 8 минут и 13 секунд
а, понятно. там новая опция
Код

project properties -> Configuration Properties -> C/C++ -> General -> SDL checks -> Yes(default)/No

PM MAIL   Вверх
lllJollyRogerlll
Дата 22.11.2014, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 20.11.2014

Репутация: нет
Всего: нет



Цитата(sQu1rr @ 20.11.2014,  18:05)
Это не ошибка, это предупреждение, которое впринципе достаточно понятно говорит, что strcpy небезопасна (так как может привести к переполению буфера - она не проверяет границы), и советует использовать strcpy_s вместо нее. Вы можете это предупреждение проигнорировать вот так, если мне не изменяет память
Код

#define _CRT_SECURE_NO_WARNINGS


А лучше, воспользуйтесь советом и используйте strcpy_s, указывая границу:
Код

// вместо
strcpy( foo, bar );
// пишите
strcpy_s( foo, 10, bar ); // где 10 - это максимальная длина строки на перезапись


Пробовал через #define убрать вот это предупреждение, все та же ошибка и не компилирует.. Ну не важно, так как помогло второе решение, вот с функцией strcpy_s(). Но не могу понять, ведь strncpy() по сути выполняет те же действия, только там указывается конкретное количество символов для копирования. Этим она как бы и безопаснее, чем strcpy(), но и с ней та же ошибка..
PM MAIL   Вверх
sQu1rr
Дата 23.11.2014, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(lllJollyRogerlll @  22.11.2014,  19:12 Найти цитируемый пост)
strncpy() по сути выполняет те же действия

Почитайте тут: http://msdn.microsoft.com/en-us/library/5dae5d43(VS.80).aspx
Безопасная версия принимает 4 аргумента а не 3.
PM MAIL Skype GTalk   Вверх
Dem_max
Дата 24.11.2014, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Нужно в cpp добавить 
Код

#pragma warning(disable:4996)


или

user posted image

Это сообщение отредактировал(а) Dem_max - 24.11.2014, 11:03


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
JackYF
Дата 25.11.2014, 22:57 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 6
Всего: 162



Цитата(sQu1rr @  20.11.2014,  17:05 Найти цитируемый пост)
А лучше, воспользуйтесь советом и используйте strcpy_s

Возражаю. По возможности используйте стандартные, более переносимые функции.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
sQu1rr
Дата 26.11.2014, 02:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(JackYF @  25.11.2014,  20:57 Найти цитируемый пост)
По возможности используйте стандартные

Так уже 3 года прошло с С11
http://en.wikipedia.org/wiki/C11_(C_standard_revision)
И вот
https://www.securecoding.cert.org/confluenc...+or+target+size

Это сообщение отредактировал(а) sQu1rr - 26.11.2014, 02:06
PM MAIL Skype GTalk   Вверх
baldina
Дата 26.11.2014, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



sQu1rr, в С но не С++
PM MAIL   Вверх
sQu1rr
Дата 26.11.2014, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(baldina @  26.11.2014,  13:25 Найти цитируемый пост)
sQu1rr, в С но не С++ 

Ну да, этот вариант я пропустил, так как функции вроде strcpy у меня ассоциируются именно с С. В С++ все таки std::string надо использовать. А из безопасных варинатов strcpy можно memcpy использовать smile
PM MAIL Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1150 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.