我正在尝试用C ++将字符串复制到TCHAR中,但是我遇到了以下错误:
错误C4996'std :: _ Copy_impl':带有可能不安全的参数的函数调用 - 此调用依赖于调用者来检查传递的值是否正确。要禁用此警告,请使用-D_SCL_SECURE_NO_WARNINGS。
这就是我想要做的。我只是将一个字符串复制到TCHAR中,然后尝试将其打印出来以确认它是正确的。
root 'index#home'
scope '/:user' do
get '/change_avatar' => 'avatars#edit', as: :change_avatar
post '/change_avatar' => 'avatars#update', as: :update_avatar
get '/edit' => 'users#edit', as: :edit_user
delete '/' => 'users#destroy', as: :destroy_user
post '/playlists' => 'playlists#create', as: :playlists
end
scope '/:user/:playlist' do
get '/' => 'playlists#show', as: :show_playlist
get '/edit' => 'playlists#edit', as: :edit_playlist
patch '/' => 'playlists#update', as: :update_playlist
delete '/' => 'playlists#destroy', as: :destroy_playlist
post '/tracks' => 'tracks#create', as: :tracks
end
scope '/:user/:playlist/:track' do
get '/' => 'tracks#show', as: :show_track
get '/edit' => 'tracks#edit', as: :edit_track
patch '/' => 'tracks#update', as: :update_track
delete '/' => 'tracks#destroy', as: :destroy_track
delete '/photos/:id' => 'photos#destroy', as: :destroy_photo
end
EDIT 如何“使用-D_SCL_SECURE_NO_WARNINGS”作为消息状态?
答案 0 :(得分:4)
编译器警告说。您可以在#define _SCL_SECURE_NO_WARNINGS
语句之前添加#include
,或将-D_SCL_SECURE_NO_WARNINGS
标志添加到项目的编译器输入标记中。
但是,这不是一个合适的解决方案。当std::copy()
映射到char
而不是TCHAR
时,TCHAR
不足以将基于wchar_t
的字符串转换为基于char
的字符串。复制字符1对1仅适用于ASCII字符(您的示例正在使用),但在使用非ASCII字符时失败,因为生成的TCHAR[]
数组可能需要比TCHAR
更多的元素{ {1}}报告。在这种情况下,您确实需要使用str.size()
或MultiByteToWideChar
之类的数据转换。
试试这个:
std::wstring_convert
或更简单(如@MicroVirus建议):
#include "stdafx.h"
#include <string>
using namespace std;
typedef basic_string<TCHAR> TCHARstring;
TCHARstring string2TCHAR(const string &s)
{
#ifdef UNICODE
TCHARstring tstr;
int size = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), NULL, 0);
if (size > 0)
{
tstr.resize(size);
MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), &tstr[0], size);
}
return tstr;
#else
return s;
#endif
}
int main()
{
string str = "C:\\windows\\system32\\calc.exe";
TCHARstring tstr = string2TCHAR(str);
_tprintf(_T("%s"), tstr.c_str());
/*
or:
#ifdef UNICODE
wcout << tstr;
#else
cout << tstr;
#endif
*/
return 0;
}
但你真的应该停止使用#include "stdafx.h"
#include <string>
using namespace std;
typedef basic_string<TCHAR> TCHARstring;
int main()
{
TCHARstring str = TEXT("C:\\windows\\system32\\calc.exe");
_tprintf(_T("%s"), tstr.c_str());
/*
or:
#ifdef UNICODE
wcout << tstr;
#else
cout << tstr;
#endif
*/
return 0;
}
。其主要目的是通过允许开发人员为两个平台使用单个代码库来帮助将传统的Win9x / ME ANSI代码迁移到NT4 + Unicode。但是,没有人为Win9x / ME开发,所以你应该坚持使用Unicode:
TCHAR
或者至少继续按原样使用int main()
{
wstring str = L"C:\\windows\\system32\\calc.exe";
wprintf(L"%s", str.c_str());
// or: wcout << str;
return 0;
}
并让操作系统在API层处理ANSI-&gt; Unicode转换(不推荐,但仍然支持):
string
否则,如果要在Unicode API中使用ANSI int main()
{
string str = "C:\\windows\\system32\\calc.exe";
printf("%s", str.c_str());
// or: cout << str;
return 0;
}
值,则必须进行手动转换:
string
答案 1 :(得分:2)
A&#39;技巧&#39;在Windows中使用TCHAR
以及我更喜欢使用的STL字符串是定义我自己的tstring
类型:
typedef std::basic_string<TCHAR> tstring;
然后,我到处都使用tstring
而不是std::string
。这样,如果使用&#34;多字节字符集编译&#34;对于字符集,它等于std::string
,并且在使用&#34; Unicode字符集&#34;进行编译时它等于std::wstring
。
最棒的是,这可以避免将其复制到TCHAR
数组,并且可以直接将c_str()
属性与_tprintf
以及 TCHAR.h 标题。它也摆脱了警告,这指出了一个潜在的问题。
答案 2 :(得分:1)
现代编译器强制实施安全编码,以提高代码质量。
早期C设计了一个像$gameid = 5;
$game{$gameid} = active;
这样的函数,它将新行读入缓冲区。
这导致程序崩溃(缓冲区溢出),然后有些人发现他们可以“接管”程序,并允许远程攻击者接管计算机。
现代gets( buffer );
设计尝试提供相同类型的功能,而没有固定大小缓冲区的风险。
投诉是,在复制到szAppName时,C++
无法检查std::copy
是否足够大,如果不是,那么您的程序就容易受到攻击。
在您的情况下,您已创建了正确大小的缓冲区,并且警告没有帮助。
szAppName
中存在不同类型的漏洞。这是为了获取带有格式说明符的字符串并打印出参数。
考虑_tprintf
还
_tprintf( "%s", szAppName ); // avoid _tprintf exploit.
因为这会避免警告。