c++ - 使用带有 LPTSTR 类型参数的 std::copy
问题描述
我正在使用 Win32 API,我需要复制使用 捕获的参数argv
,问题是,代码必须同时符合 ASCII 和 UNICODE,这是 Windows 中 C/C++ 的问题。
除此之外,如果可能,我必须使用 C++ 而不是 C,所以我std::copy
用来复制类型LPTSTR
(或TCHAR*
)的参数,我可以使用_tcscpy_s
,但正如我所说,它必须尽可能是 C++。
注意:我不能使用std::wstring
orstd::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;
}
我的问题是:
代码是否安全,和/或是否有更好的替代方案(最好使用 C++)?
(不仅是复制部分,而且是整个想法)
解决方案
你应该使用std::basic_string
:
using tstring = std::basic_string<TCHAR>;
它自己处理所有的复制。每当您需要与某些 C API 对话时,请使用str.c_str()
const 指针和str.data()
(在 C++17 之后)或&str[0]
(C++17 之前)用于非 const 指针。
#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;
}
推荐阅读
- python - 如何将一个较小 DataFrame 的值添加到另一个混合类型 DataFrame 的一部分,但仅添加到某个任意行索引之后的行?
- python - 将函数中的值放入上下文中
- java - 如何在 C++ 中捕获 sdbus::Error 异常?
- node.js - Windows但Mac上的Nodejs zlib gunzip“无效块类型”错误
- javascript - 在房间重新连接后,套接字 io 未接收到事件
- encryption - 准备在 EME 中使用的音频文件
- parsing - Haskell:函数中的非穷举模式阻止另一个函数执行,即使它没有被使用
- flutter - Flutter MaterialPageRoute 作为 fullscreenDialog 出现在 BottomNavigationBar 下方
- javascript - 在百里香中预填充下拉选择列表
- java - 在 Java 8 Streaming 中,如何从收集器中调用方法?