pjhelp Ответов: 6

Как избежать предупреждающего сообщения, связанного с "strcpy()"?


static char BASED_CODE szFilter[] = "HTML Files (*.xls)|*.xls|All Files (*.*)|*.*||";
 
    if (AppMarketID == 12)
    { 
      strcpy(szFilter,"HTML Files (*.xlsx)|*.xlsx|All Files (*.*)|*.*||");     
    }
CFileDialog dia(FALSE, "", default_name, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);


Я получаю предупреждение как -
warning 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 name]

Это может быть опасно после Microsoft, потому что символ "\0 " определяет конец строки.

6 Ответов

Рейтинг:
29

Richard MacCutchan

Теперь вы опубликовали этот же вопрос три раза: здесь[^], здесь[^], и вот. Вам также были даны некоторые полезные советы о том, как решить эту проблему. Может быть, вам пора пойти и почитать об основах указателей и массивов, об их различиях и почему strcpy() может быть опасным.


Sergey Alexandrovich Kryukov

...а также проголосовал против этого ответа на 1 (может быть, не ОП, хотя; я проголосовал за 5).
Я полностью с вами согласен.

ОП следует предупредить: повторные публикации должны быть удалены, повторные публикации будут сообщаться как спам и злоупотребление мерами модерации.

--СА

Richard MacCutchan

Спасибо, ОП довольно новый, так что, вероятно, все еще изучает протокол.

Sergey Alexandrovich Kryukov

Сгодится и немного лошадиного чутья...
--СА

Рейтинг:
2

Hans Dietrich

В этом случае нет никаких причин использовать strcpy вообще, тем более что вы имеете дело со статическими строками:

static char BASED_CODE szFilter1[] = "HTML Files (*.xls)|*.xls|All Files (*.*)|*.*||";
static char BASED_CODE szFilter2[] = "HTML Files (*.xlsx)|*.xlsx|All Files (*.*)|*.*||";
CFileDialog dia(FALSE, "", default_name, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, (AppMarketID == 12) ? szFilter2 : szFilter1);


Sergey Alexandrovich Kryukov

Он он он. А 5.
--СА

Рейтинг:
1

cute_friend7077

Свойства проекта->Свойства конфигурации->C/C++->препроцессор->определения препроцессора
Нажаться кнопку с многоточием (...)
введите любые определения, которые вам нравятся, разделенные "\n"ie
_CRT_SECURE_NO_WARNINGS


Hans Dietrich

В общем, если нет альтернативы, это плохая идея, чтобы изменить свойства проекта только из-за того, что находится в исходном файле. Что, если бы вы взяли исходный файл и использовали его в другом проекте через несколько месяцев? Тогда вам придется потратить время, пытаясь понять, почему вы получаете предупреждение по одному проекту, но не по другому. Что еще хуже, если кто-то другой изменил свойства, а вы об этом не знали? Пустая трата времени.

Рейтинг:
0

Niklas L

Просто использовать предоставляя strcpy_s[^] чтобы избежать предупреждения.

Я также могу предложить вам использовать std::string или CString для упрощения вещей.


Guyverthree

например, изменение функции удаления предупреждений редко бывает хорошей идеей.

Дж

Niklas L

И почему не стоит менять функцию, если вы получаете предупреждение? Эти предупреждения существуют не просто так. Слишком много программистов сделали слишком много ошибок, связанных с strcpy и переполнением буфера за эти годы. Microsoft решила что-то с этим сделать, продвигая новые "безопасные" версии старых функций манипулирования строками. Это на самом деле то, что рекомендует Microsoft.

Guyverthree

Извините, что это был плохо написанный комментарий.

Он должен был сказать: мне нравится менять функцию, подавление предупреждений редко бывает хорошей идеей.

Я согласен, что изменение функции-это правильная вещь, а не просто подавление предупреждения, как другие решения. Я проголосовал за 5. :)

Niklas L

А! Потерялся в переводе. Извините... и спасибо!

Sergey Alexandrovich Kryukov

Правильный ответ, согласился бы на std (но вряд ли на CString), мой 5.
--СА

Niklas L

Ну, в конце концов, это же МФЦ. На самом деле, худший способ-это использовать статический символ*. В Примере на MSDN используется статический символ*, и он прост в использовании. Но что произойдет в тот день, когда вы захотите локализовать свое приложение? CString::LoadString() было бы намного лучше. Но я согласен, я предпочитаю std::string над CString, когда могу. Спасибо за 5.

Sergey Alexandrovich Kryukov

Я действительно заметил это через некоторое время после того, как опубликовал свой комментарий к CString. В данном случае это достаточное оправдание; не было бы для хорошего универсального кода-лучше быть переносимым.
Спасибо.
--СА

Рейтинг:
0

krmed

Чтобы процитировать ваше собственное сообщение:

To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.


Hans Dietrich

Поскольку это обычно указывается в stdafx.h, а не в исходном файле, это плохая идея. Что, если бы вы взяли исходный файл и использовали его в другом проекте через несколько месяцев? Тогда вам придется потратить время, пытаясь понять, почему вы получаете предупреждение по одному проекту, но не по другому. Если вы хотите быть активным в отношении этого предупреждения, то сделайте то, что я делаю; поместите эту прагму в верхней части каждого исходного файла, где это необходимо:
#pragma warning(disable : 4996) // отключить фиктивное предупреждение об устаревании
Обратите внимание, что я говорю "фиктивный", потому что это именно то, что есть; вы можете достичь того же эффекта с помощью strncpy(). Да, вы можете ошибаться в параметре длины в strncpy, так же как вы можете ошибаться в параметре длины в strcpy_s. С обеими функциями вы должны быть осторожны.

Niklas L

strncpy() не гарантирует нулевой Терминатор в целевой строке, если буфер заполнен, что является реальной проблемой. Таким образом, strncpy() также помечается как небезопасный.
Однако шаблонные версии strcpy_s (), работающие с массивами, довольно хороши.

Hans Dietrich

Стандартная практика при работе с "неизвестными" строками заключается в том, чтобы установить последний символ равным нулю после копирования. (Я вижу, что это делается в Unix больше, чем в Windows.) Да, функции _s хороши таким образом, но утверждать, что они безопасны, - это шутка. Смотрите, например, анализ Дэнни Калева здесь:
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=260

Niklas L

Да, но с strncpy (), являющимся странным исключением.

Кстати, хорошая ссылка.

krmed

Я не сказал, что это хорошая идея, просто ответил на вопрос ОП. Как я могу избежать этого?..
На мой взгляд (и то, что я всегда делал), подходящее решение-использовать strcpy_s (или _tcscpy_s).

strncpy на самом деле не эквивалентен, так как он не добавляет null в конце строки, в то время как strcpy_s действительно добавляет его и гарантирует, что есть место для завершающего null.

krmed

Я бы подумал, что если кто-то отрицает ответ, то он должен, по крайней мере, добавить комментарий о том, почему он так себя чувствует. Этого почти достаточно, чтобы отбить у кого-либо охоту публиковать какие-либо ответы.

Рейтинг:
0

Michael Haephrati

Самым быстрым решением было бы добавить

#pragma warning(disable:4996)

к
stdafx.h


Это не самое лучшее решение, и это предупреждение здесь не просто так, но если это сообщение об ошибке задерживает вас и вы должны устранить его как можно скорее, это то, что вы должны сделать.


CPallini

Это задержало операцию на семь долгих лет. :-)

Michael Haephrati

Я уверен, что теперь нас ждут 7 хороших лет :)

CHill60

Ничем не отличается от комментария, добавленного к решению 1, которое было предложено 7 лет назад, так действительно ли стоило воскрешать такой старый пост?

Michael Haephrati

Просто чтобы объяснить дальше, когда я выбираю "неотвеченные вопросы" или ищу вопросы (например, в c/ c++) Я добираюсь до этого и других вопросов независимо от их даты. Если это концептуальная ошибка, ее следует изменить. Я просто пытался помочь...