При компиляции такого кода
#include <iostream>
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
int main() {
const int maxSymbols = 15;
char* word1 = new char[maxSymbols];
char* word2 = new char[maxSymbols];
cout << "Enter five words : ";
cin >> word1;
cin >> word2;
cout << endl << strcat(word1, word2);
}
Появляется ошибка C4996 ‘strcat’: This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
После появления этой ошибки в начале дописал #define _CRT_SECURE_NO_WARNINGS
но это ничего не изменило.
Помогите пожалуйста.
-
Вопрос заданболее года назад
-
1288 просмотров
Пригласить эксперта
Попробуйте ввести более 10 символов в word1 и word2 и у вас программа непредсказуемо упадёт.
Если использовать strcat_s, то она проверит граничные условия и выдаст ошибку, если они не выполняются.
Для использования strcat_s нужно немного переписать программу — обработать ошибку и знать размер первого буфера.
Данил Васькевич, прикинь, блин! Или как компилятор советует вместо strcat использовать strcat_s, или указать дифайн _CRT_SECURE_NO_WARNINGS (в Visual Studio его можно указать в свойствах проекта, глобально). Ну лучше всё же не пользоваться небезопасными функциями, а перейти на функции с суфиксом _s везде где только возможно, а не только в этом случае. Дифайн _CRT_SECURE_NO_WARNINGS это плохое решение, подходит на «только сейчас и для старого кода чтобы поддерживался», а новый код не надо на него расчитывать, надо пользоваться безопасными функциями.
-
Показать ещё
Загружается…
09 февр. 2023, в 15:06
2000 руб./за проект
09 февр. 2023, в 15:02
12000 руб./за проект
09 февр. 2023, в 14:22
1500 руб./за проект
Минуточку внимания
Здравствуйте, изучаю Win32 API, делаю все как в примере — (в примере используется VS 6, я пользуюсь VS Community 2015)
выдает ошибку:
Ошибка C4996
‘strcat’: This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
Hello2 c:usersгеоргийdocumentsvisual studio 2015projectsuniversalbasehello2kwnd.cpp
вот сам код:
/////////////////////////////////////////////////////////////////////////////// /// KWnd.cpp /// /////////////////////////////////////////////////////////////////////////////// #include "KWnd.h" KWnd::KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow, LRESULT(WINAPI *pWndProc)(HWND, UINT, WPARAM, LPARAM), LPCSTR menuName, int x, int y, int width, int height, UINT classStyle, DWORD windowStyle, HWND hParent) { char szClassName[] = "KWndClass"; wc.cbSize = sizeof(wc); wc.style = classStyle; wc.lpfnWndProc = pWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = menuName; wc.lpszClassName = szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // Регистрируем класс окна if (!RegisterClassEx(&wc)) { char msg[100] = "Не могу зарегестрировать class: "; strcat(msg, szClassName); MessageBox(NULL, msg, "Ошибка", MB_OK); } // Создаем окно hWnd = CreateWindow(szClassName, windowName, windowStyle, x, y, width, height, hParent, HMENU(NULL), hInst, NULL); if (!hWnd) { char text[100] = "Не могусоздать окно: "; strcat(text, windowName); MessageBox(NULL, text, "Ошибка", MB_OK); return; } // Показываем окно ShowWindow(hWnd, cmdShow); }
Пожалуйста Подскажите что не так сделал?
What’s the error in this code? I’ve got an error
error C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead
What it’s mean? Another question — the declaration of the struct and the function prototype is legal?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char *join(char *, char *);
printf("%s n", join("duck", "soup"));
}
char *join(char *s1, char *s2)
{
struct {
char buf[256];
} string;
string.buf = "abcd";\ new line. error l-value.
return strcat(strcpy(string.buf, s1), s2);
}
The new line — why there is an error? isn’t string.buf
a char pointer? what’s the problem with char *s="abcd"
?
Thanks!:)
asked Feb 26, 2015 at 10:20
Dvir NaimDvir Naim
3351 gold badge3 silver badges12 bronze badges
7
The error message is entirely self-explanatory. It’s not clear what it is you don’t understand. For example, in your join
function, terrible things would happen if the two strings together are longer than 255 characters.
Also, your join
function is totally broken. It returns a pointer to a buffer that no longer exists once it returns since you allocated it on the stack that you are returning from.
answered Feb 26, 2015 at 10:23
David SchwartzDavid Schwartz
177k17 gold badges208 silver badges272 bronze badges
1
That’s your implementation trying to be helpful.
You can stop it from doing that by adding the following #define
at the top of your code
#define _CRT_SECURE_NO_WARNINGS
or follow the suggestion and use strcat_s()
.
answered Feb 26, 2015 at 10:24
pmgpmg
105k12 gold badges125 silver badges198 bronze badges
The first message is because strcat doesn’t check if the target storage is big enough to hold the concatenated string. You might get a buffer overflow. strcat_s
has an additional parameter which is the buffer length. It will make sure there is no buffer overflow.
Regarding you second question, the code in join()
is bogus.
What you do is declare a local variable that is an array of 256 char. As a local variable it will be «destroyed» when join()
terminates.
You then copy s1
into this buffer. Note that the buffer could be too small and you would get a buffer overflow.
Then you call strcat
with the local variable buffer as first argument. The result is that s2
will be appended to s1
in the local variable buffer.
The value return by strcat
is a pointer on the buffer.
When join()
returns, the buffer is «destroyed» and the pointer becomes invalid.
Note that another problem in you code is to declare the function join()
inside of main. You must move this line out of the main function.
The way you defined your struct and string variable is correct. It is the way you perform the join()
that is bogus.
Arun A S
5,9974 gold badges31 silver badges42 bronze badges
answered Feb 26, 2015 at 10:33
chmikechmike
20.4k21 gold badges80 silver badges100 bronze badges
2
suas_hiatus 2 / 2 / 0 Регистрация: 14.06.2014 Сообщений: 71 |
||||
1 |
||||
06.09.2015, 19:55. Показов 7212. Ответов 4 Метки нет (Все метки)
Ошибка C4996 ‘strcat’: This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. Подскажите, может их заменить как ( если заменять на strcpy_s то возникает ошибка отсутствия аргументов, так что тоже не знаю что делать) Подскажите, что делать? :#
__________________
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
06.09.2015, 19:55 |
Ответы с готовыми решениями: Что лучше применить: sprintf или strcat и strcpy? Писал программу, использовал sprintf(cVar1, "%s",… Strcpy_s Помогите, пожалуйста! Решаю 2 упражнение главы 12 учебника Стивена Прата. Есть… Использование strcpy_s strcpy/strcpy_s Есть класс (упрощенно): class const_string 4 |
easybudda Модератор 11659 / 7172 / 1704 Регистрация: 25.07.2009 Сообщений: 13,142 |
||||
06.09.2015, 19:59 |
2 |
|||
Сообщение было отмечено suas_hiatus как решение Решение
To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
в самом начале файла. К чему только всё это в С++? Чем std::string не угодил?
1 |
2 / 2 / 0 Регистрация: 14.06.2014 Сообщений: 71 |
|
06.09.2015, 20:05 [ТС] |
3 |
Добавлено через 30 секунд
Чем std::string не угодил? Да без понятия, если честно. Только начинаю изучать, и встретилась эта функция. Я так понимаю, что я делаю через левое колено, и можно было через std::string? А за ответ спасибо, заработало)
0 |
Модератор 11659 / 7172 / 1704 Регистрация: 25.07.2009 Сообщений: 13,142 |
|
06.09.2015, 20:21 |
4 |
Я так понимаю, что я делаю через левое колено, и можно было через std::string? Можно и так сказать. strcpy(), strcat() и иже с ними — наследие языка С, где строки представлялись последовательностью байтов, оканчивающейся нулевым байтом. В С++ есть довольно удобный класс string. Если точно для себя решили освоить именно С++, а не С, рекомендую для работы со строками им и пользоваться. Но, разумеется, представление о строках в С-стиле и функциях для работы с ними лишним не будет.
0 |
2758 / 1912 / 569 Регистрация: 05.06.2014 Сообщений: 5,561 |
|
06.09.2015, 20:22 |
5 |
Да без понятия, если честно. Только начинаю изучать, и встретилась эта функция. Я так понимаю, что я делаю через левое колено, и можно было через std::string? Через левое колено делали вашу Студию, которая отказывается использовать стандартную функцию strcat и хочет НЕ стандартную strcat_s.
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
06.09.2015, 20:22 |
5 |
2 Августа 2017
Время чтения: 5 минут
Компилятор в Visual Studio сильно отличается от привычных большинству программистов GCC или CLANG, из-за чего при написании кода на C или C++ очень часто возникают неожиданные проблемы в виде ошибки использования стандартных функций, например, scanf, fopen, sscanf и тому подобным. Студия предлагает заменять функции на безопасные (повезёт, если нужно просто добавить _s к функции с ошибкой, но нередко в этих функциях идёт иной набор аргументов, нежели в обычной программе). Если вы не готовы с этим мириться, то этот пост для вас!
Давайте для начала создадим обычный консольный проект в Visual Studio и напишем простенькую программу, которая запрашивает ввод двух чисел, вводит их и затем выводит на экран.
#include "stdafx.h" #include <stdio.h> int main() { int a, b; printf("Enter a: "); scanf("%d", &a); printf("Enter b: "); scanf("%d", &b); printf("a: %d, b: %dn", a, b); return 0; }
Попробовав выполнить сборку проекта, обнаружим те самые ошибки.
Чтобы Visual Studio не тратила ваши нервы, сделаем следующее:
1. Выберем пункт «Проект» в верхнем меню
2. В открывшемся списке щёлкнем по «Свойства название_проекта»
Программа, вводящая два числа и выводящая их
Ошибка компиляции из-за небезопасности функций
Проект — Свойства {навание проекта}
3. В появившемся окне выберем Свойства конфигурации
, C/C++
, Препроцессор
4. В строке Определения препроцессора
допишем в самый конец строку ;_CRT_SECURE_NO_WARNINGS
5. Нажмём ОК
Свойства конфигурации
Определения препроцессора
Нажимаем OK
6. Попробуем заново выполнить сборку проекта:
Успешная сборка проекта
Ошибки исчезли, сборка прошла успешно и программа прекрасно работает! Теперь можно писать код как обычно, не переживая о необычном поведении Visual Studio!
Программист, сооснователь programforyou.ru, в постоянном поиске новых задач и алгоритмов
Языки программирования: Python, C, C++, Pascal, C#, Javascript
Выпускник МГУ им. М.В. Ломоносова
Hello!
I programmed this member function for a «client» class, where I am receiving through command line something like this: host/path1/path2/path3/filename
And in this function I trying to separate the information between the ‘/’ and store it in my class variables host, path and filename (all of them are of type char*)
However this is not working, when compiling I get:
error C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
error C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
I would like to understand why this functions are «unsafe» and any information about this is well received.
Should I do this another way, like trying to do this with strings?
Should I disable deprecation with _CRT_SECURE_NO_WARNINGS?
I am working in visual studio
Here is my function checkCommand:
bool Client::checkCommand(int argc_, char* arguments)
{
if (argc_ == 2)
{
char* tokens[MAXTOKENS] = { };
char* tokenPtr = strtok(arguments, "/");
int i, totalTokens = 0;
while (tokenPtr != NULL && totalTokens < MAXTOKENS)
{
tokens[totalTokens] = tokenPtr;
tokenPtr = strtok(NULL, "/");
}
this->host = tokens[0];
this->filename = tokens[totalTokens];
this->path = tokens[2];
/*here i concatenate my first path to the rest of the paths*/
for (i = 3; i < totalTokens; i++)
{
strcat(this->path, tokens[i]);
strcat(this->path, "/");
}
return true;
}
else
return false;
}
thank you!