首页 > 解决方案 > 使用带有 LPTSTR 类型参数的 std::copy

问题描述

我正在使用 Win32 API,我需要复制使用 捕获的参数argv,问题是,代码必须同时符合 ASCII 和 UNICODE,这是 Windows 中 C/C++ 的问题。

除此之外,如果可能,我必须使用 C++ 而不是 C,所以我std::copy用来复制类型LPTSTR(或TCHAR*)的参数,我可以使用_tcscpy_s,但正如我所说,它必须尽可能是 C++。

注意:我不能使用std::wstringorstd::string因为这些必须传递给CreateProcess()并且参数必须是类型TCHAR*,以便它可以将其转换为LPTSTRLPWSTR依赖于编码。

这是一个控制台可执行最小可重现示例:

#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++)?

(不仅是复制部分,而且是整个想法)

标签: c++winapitcharlptstrstdcopy

解决方案


你应该使用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;
}

推荐阅读