将 std::copy 与 LPTSTR 类型参数一起使用
Using std::copy with LPTSTR type argument
我正在使用 Win32 API,我需要复制使用 argv
捕获的参数,问题是,代码必须同时符合 ASCII 和 UNICODE,这是 C/C++ 在 Windows.
除此之外,我必须尽可能使用 C++ 而不是 C,因此我使用 std::copy
来复制 LPTSTR
(或 TCHAR*
)类型的参数,我可以使用 _tcscpy_s
但正如我所说,它必须尽可能使用 C++。
注意:我不能使用 std::wstring
或 std::string
因为它们必须传递给 CreateProcess()
并且参数必须是 TCHAR*
类型以便它可以转换取决于编码 LPTSTR
或 LPWSTR
。
这是一个控制台可执行文件最小可重现示例:
#include <windows.h>
#include <tchar.h>
#include <corecrt_io.h>
#include <fcntl.h>
#include <iostream>
#ifdef UNICODE
#define tcout wcout
#define tcin wcin
#else
#define tcout cout
#define tcin cin
#endif
int _tmain(int argc, LPTSTR argv[])
{
using std::copy;
using std::tcout;
using std::tcin;
constexpr int size = 1024;
TCHAR fileName[size];
#ifdef UNICODE
_setmode(_fileno(stdin), _O_WTEXT);
_setmode(_fileno(stdout), _O_WTEXT);
#endif
if (argc > 1)
{
copy(&argv[1][0], &argv[1][1023], fileName); //is this copy ok?
}
else
{
tcout << "Program name: ";
tcin >> fileName;
}
tcout << fileName;
}
我的问题是:
代码安全吗,and/or是否有更好的替代方案(最好使用 C++)?
(不仅是复制部分,还有整个想法)
你应该使用 std::basic_string
:
using tstring = std::basic_string<TCHAR>;
它自己处理所有的复制。每当你需要与某些 C API 交谈时,使用 str.c_str()
作为 const 指针和 str.data()
(C++17 之后)或 &str[0]
(C++17 之前)对于非常量指针。
#include <windows.h>
#include <tchar.h>
#include <corecrt_io.h>
#include <fcntl.h>
#include <iostream>
#include <string>
using tstring = std::basic_string<TCHAR>;
#ifdef UNICODE
static auto& tcout = std::wcout;
static auto& tcin = std::wcin;
#else
static auto& tcout = std::cout;
static auto& tcin = std::cin;
#endif
int _tmain(int argc, LPTSTR argv[])
{
tstring fileName;
if (argc > 1)
{
fileName = argv[1];
}
else
{
tcout << _T("Program name: ");
tcin >> fileName;
}
tcout << fileName;
return 0;
}
我正在使用 Win32 API,我需要复制使用 argv
捕获的参数,问题是,代码必须同时符合 ASCII 和 UNICODE,这是 C/C++ 在 Windows.
除此之外,我必须尽可能使用 C++ 而不是 C,因此我使用 std::copy
来复制 LPTSTR
(或 TCHAR*
)类型的参数,我可以使用 _tcscpy_s
但正如我所说,它必须尽可能使用 C++。
注意:我不能使用 std::wstring
或 std::string
因为它们必须传递给 CreateProcess()
并且参数必须是 TCHAR*
类型以便它可以转换取决于编码 LPTSTR
或 LPWSTR
。
这是一个控制台可执行文件最小可重现示例:
#include <windows.h>
#include <tchar.h>
#include <corecrt_io.h>
#include <fcntl.h>
#include <iostream>
#ifdef UNICODE
#define tcout wcout
#define tcin wcin
#else
#define tcout cout
#define tcin cin
#endif
int _tmain(int argc, LPTSTR argv[])
{
using std::copy;
using std::tcout;
using std::tcin;
constexpr int size = 1024;
TCHAR fileName[size];
#ifdef UNICODE
_setmode(_fileno(stdin), _O_WTEXT);
_setmode(_fileno(stdout), _O_WTEXT);
#endif
if (argc > 1)
{
copy(&argv[1][0], &argv[1][1023], fileName); //is this copy ok?
}
else
{
tcout << "Program name: ";
tcin >> fileName;
}
tcout << fileName;
}
我的问题是:
代码安全吗,and/or是否有更好的替代方案(最好使用 C++)?
(不仅是复制部分,还有整个想法)
你应该使用 std::basic_string
:
using tstring = std::basic_string<TCHAR>;
它自己处理所有的复制。每当你需要与某些 C API 交谈时,使用 str.c_str()
作为 const 指针和 str.data()
(C++17 之后)或 &str[0]
(C++17 之前)对于非常量指针。
#include <windows.h>
#include <tchar.h>
#include <corecrt_io.h>
#include <fcntl.h>
#include <iostream>
#include <string>
using tstring = std::basic_string<TCHAR>;
#ifdef UNICODE
static auto& tcout = std::wcout;
static auto& tcin = std::wcin;
#else
static auto& tcout = std::cout;
static auto& tcin = std::cin;
#endif
int _tmain(int argc, LPTSTR argv[])
{
tstring fileName;
if (argc > 1)
{
fileName = argv[1];
}
else
{
tcout << _T("Program name: ");
tcin >> fileName;
}
tcout << fileName;
return 0;
}