Strcat c ошибка c4996

При компиляции такого кода

#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
но это ничего не изменило.
Помогите пожалуйста.


  • Вопрос задан

    более двух лет назад

  • 1656 просмотров

Пригласить эксперта

Попробуйте ввести более 10 символов в word1 и word2 и у вас программа непредсказуемо упадёт.
Если использовать strcat_s, то она проверит граничные условия и выдаст ошибку, если они не выполняются.
Для использования strcat_s нужно немного переписать программу — обработать ошибку и знать размер первого буфера.

Данил Васькевич, прикинь, блин! Или как компилятор советует вместо strcat использовать strcat_s, или указать дифайн _CRT_SECURE_NO_WARNINGS (в Visual Studio его можно указать в свойствах проекта, глобально). Ну лучше всё же не пользоваться небезопасными функциями, а перейти на функции с суфиксом _s везде где только возможно, а не только в этом случае. Дифайн _CRT_SECURE_NO_WARNINGS это плохое решение, подходит на «только сейчас и для старого кода чтобы поддерживался», а новый код не надо на него расчитывать, надо пользоваться безопасными функциями.


  • Показать ещё
    Загружается…

04 июн. 2023, в 13:54

1500 руб./за проект

04 июн. 2023, в 13:43

2000 руб./за проект

04 июн. 2023, в 13:14

200000 руб./за проект

Минуточку внимания

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 Naim's user avatar

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 Schwartz's user avatar

David SchwartzDavid Schwartz

179k17 gold badges214 silver badges277 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

pmg's user avatar

pmgpmg

106k13 gold badges126 silver badges199 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's user avatar

Arun A S

6,3524 gold badges28 silver badges42 bronze badges

answered Feb 26, 2015 at 10:33

chmike's user avatar

chmikechmike

20.6k21 gold badges82 silver badges102 bronze badges

2

Здравствуйте, изучаю 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);
}

Пожалуйста Подскажите что не так сделал?

When I try to do things like this:

char* prefix = "Sector_Data\sector";
char* s_num = "0";
std::strcat(prefix, s_num);
std::strcat(prefix, "\");

and so on and so forth, I get a warning

warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead.

Why is strcat considered unsafe, and is there a way to get rid of this warning without using strcat_s?

Also, if the only way to get rid of the warning is to use strcat_s, how does it work (syntax-wise: apparently it does not take two arguments).

asked Jun 1, 2009 at 19:57

2

If you are using c++, why not avoid the whole mess and use std::string. The same example without any errors would look like this:

std::string prefix = "Sector_Data\sector";
prefix += "0";
prefix += "\"

no need to worry about buffer sizes and all that stuff. And if you have an API which takes a const char *, you can just use the .c_str() member;

some_c_api(prefix.c_str());

answered Jun 1, 2009 at 20:33

Evan Teran's user avatar

Evan TeranEvan Teran

87.1k31 gold badges178 silver badges238 bronze badges

1

Because the buffer, prefix, could have less space than you are copying into it, causing a buffer overrun.
Therefore, a hacker could pass in a specially crafted string which overwrites the return address or other critical memory and start executing code in the context of your program.

strcat_s solves this by forcing you to pass in the length of the buffer into which you are copying the string; it will truncate the string if necessary to make sure that the buffer is not overrun.

google strcat_s to see precisely how to use it.

answered Jun 1, 2009 at 20:02

Drew Hoskins's user avatar

Drew HoskinsDrew Hoskins

4,16820 silver badges23 bronze badges

5

You can get rid of these warning by adding:

_CRT_SECURE_NO_WARNINGS

and

_SCL_SECURE_NO_WARNINGS

to your project’s preprocessor definitions.

answered Jun 1, 2009 at 20:41

Dusty Campbell's user avatar

1

That’s one of the string-manipulation functions in C/C++ that can lead to buffer overrun errors.

The problem is that the function doesn’t know what the size of the buffers are. From the MSDN documentation:

The first argument, strDestination,
must be large enough to hold the
current strDestination and strSource
combined and a closing »;
otherwise, a buffer overrun can occur.

strcat_s takes an extra argument telling it the size of the buffer. This allows it to validate the sizes before doing the concat, and will prevent overruns. See http://msdn.microsoft.com/en-us/library/d45bbxx4.aspx

answered Jun 1, 2009 at 20:04

Herms's user avatar

HermsHerms

37.4k12 gold badges77 silver badges101 bronze badges

1

Because it has no means of checking to see if the destination string (prefix) in your case will be written past its bounds. strcat essentially works by looping, copying byte-by-byte the source string into the destination. Its stops when it sees a value «0» (notated by ») called a null terminal. Since C has no built in bounds checking, and the dest str is just a place in memory, strcat will continue going ad-infinidium even if it blows past the source str or the dest. str doesn’t have a null terminal.

The solutions above are platform-specific to your windows environment. If you want something platform independent, you have to wrangle with strncat:

strncat(char* dest, const char* src, size_t count)

This is another option when used intelligently. You can use count to specify the max number of characters to copy. To do this, you have to figure out how much space is available in dest (how much you allocated — strlen(dest)) and pass that as count.

answered Jun 1, 2009 at 20:02

Doug T.'s user avatar

Doug T.Doug T.

64k27 gold badges138 silver badges201 bronze badges

3

To turn the warning off, you can do this.

#pragma warning(disable:4996)

btw, I strongly recommend that you use strcat_s().

answered Jun 1, 2009 at 22:58

young's user avatar

youngyoung

2,15312 silver badges19 bronze badges

There are two problems with strcat. First, you have to do all your validation outside the function, doing work that is almost the same as the function:

if(pDest+strlen(pDest)+strlen(pScr) < destSize)

You have to walk down the entire length of both strings just to make sure it will fit, before walking down their entire length AGAIN to do the copy. Because of this, many programmers will simply assume that it will fit and skip the test. Even worse, it may be that when the code is first written it is GUARANTEED to fit, but when someone adds another strcat, or changes a buffer size or constant somewhere else in the program, you now have issues.

The other problem is if pSrc and pDst overlap. Depending on your compiler, strcat may very well be simple loop that checks a character at a time for a 0 in pSrc. If pDst overwrites that 0, then you will get into a loop that will run until your program crashes.

answered Jun 1, 2009 at 21:15

Dolphin's user avatar

DolphinDolphin

4,6451 gold badge30 silver badges25 bronze badges

suas_hiatus

2 / 2 / 0

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

Сообщений: 71

1

06.09.2015, 19:55. Показов 8153. Ответов 4

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


Студворк — интернет-сервис помощи студентам

C++
1
2
3
4
    strcat(name, " "); 
    strcat(lastname, " ");
    strcpy(name, (strcat(strcat(lastname, name), dlastname)));
    strcpy(nomergroup, strcat(v, nomergroup));

Ошибка 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 то возникает ошибка отсутствия аргументов, так что тоже не знаю что делать)
Либо как вообще отключить проверку кода, ибо VS 2015 года, и я не могу разобраться где он тут отключается.
Так же пробовала подключить #pragma, но не помогло, ошибка та же самая.

Подскажите, что делать? :#



0



Programming

Эксперт

94731 / 64177 / 26122

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

Сообщений: 116,782

06.09.2015, 19:55

Ответы с готовыми решениями:

Что лучше применить: sprintf или strcat и strcpy?
Win7, CodeBlocks, C++, Win32 API, ResEd.

Писал программу, использовал sprintf(cVar1, &quot;%s&quot;,…

Strcpy_s
Добрый день!

Помогите, пожалуйста! Решаю 2 упражнение главы 12 учебника Стивена Прата. Есть…

Использование strcpy_s
Добрый день.
Словил странную проблему (компилятор MVS2010)
#include&lt;iostream&gt;
#include&lt;cstring&gt;…

strcpy/strcpy_s
Добрый вечер!

Есть класс (упрощенно):

class const_string
{
public:
const_string(char…

4

easybudda

Модератор

Эксперт PythonЭксперт JavaЭксперт CЭксперт С++

11891 / 7264 / 1720

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

Сообщений: 13,293

06.09.2015, 19:59

2

Лучший ответ Сообщение было отмечено suas_hiatus как решение

Решение

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

To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

C++
1
#define _CRT_SECURE_NO_WARNINGS

в самом начале файла. К чему только всё это в С++? Чем std::string не угодил?



1



2 / 2 / 0

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

Сообщений: 71

06.09.2015, 20:05

 [ТС]

3

Добавлено через 30 секунд

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

Чем std::string не угодил?

Да без понятия, если честно. Только начинаю изучать, и встретилась эта функция. Я так понимаю, что я делаю через левое колено, и можно было через std::string?

А за ответ спасибо, заработало)



0



Модератор

Эксперт PythonЭксперт JavaЭксперт CЭксперт С++

11891 / 7264 / 1720

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

Сообщений: 13,293

06.09.2015, 20:21

4

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

Я так понимаю, что я делаю через левое колено, и можно было через std::string?

Можно и так сказать. strcpy(), strcat() и иже с ними — наследие языка С, где строки представлялись последовательностью байтов, оканчивающейся нулевым байтом. В С++ есть довольно удобный класс string. Если точно для себя решили освоить именно С++, а не С, рекомендую для работы со строками им и пользоваться. Но, разумеется, представление о строках в С-стиле и функциях для работы с ними лишним не будет.



0



2761 / 1915 / 569

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

Сообщений: 5,571

06.09.2015, 20:22

5

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

Да без понятия, если честно. Только начинаю изучать, и встретилась эта функция. Я так понимаю, что я делаю через левое колено, и можно было через std::string?

Через левое колено делали вашу Студию, которая отказывается использовать стандартную функцию strcat и хочет НЕ стандартную strcat_s.
А так да, можно было через string.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

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

Сообщений: 92,604

06.09.2015, 20:22

5

Понравилась статья? Поделить с друзьями:
  • Strava ошибка подключения к интернету
  • Stranded deep ошибка при запуске
  • Steamvr ошибка 108
  • Str object is not callable python ошибка
  • Steamui dll ошибка что делать windows 10