-1

In my Windows code in Visual Studio 2019, I'm trying to understand/best way to get a string from another function using vector and make_unique.

It's straightforward to call GetText() when using new/delete, but C26409 says "Avoid calling new and delete explicitly, use std::make_unique instead(r.11)".

C26409 recommends converting to a std::unique_ptr (or a vector), of which I've done both below, but how do I use the existing function GetText() for all declarations (new/vector/make_unique)?

Secondly, is there another way I should be rewriting GetText() so it can take as input a (new, vector, or make_unique)?

Here is my sample code.

#include <windows.h>
#include <strsafe.h>
#include <vector>
#include <memory>

void GetText(WCHAR **sText, DWORD dwTextSize)
{
    StringCchPrintfW(*sText, dwTextSize, L"this is a %s", L"test");
}

int main()
{
    auto *sResult = new WCHAR[256];
    StringCchPrintfW(sResult, 256, L"this is a %s", L"test");
    GetText(&sResult, 256);
    delete[] sResult;

    std::vector<WCHAR> sResult2(256);
    StringCchPrintfW(sResult2.data(), sResult2.size(), L"this is a %s", L"test");
    //GetText(&sResult2.data(), 256);

    auto sResult3 = std::make_unique<WCHAR[]>(256);
    StringCchPrintfW(sResult3.get(), 256, L"this is a %s", L"test");
    //GetText(&sResult3.get(), 256);    
}
JeffR
  • 765
  • 2
  • 8
  • 23
  • You'd better add a reference to that other question then, because as it stands it's difficult to figure out what you're trying to do. – Spencer Apr 07 '23 at 11:40
  • 1
    You're using the wrong types, wrong literal specifiers and wrong functions. In *C++* a string is a `std::string`, not a `char *`. Instead of `sprintf`, use `ostringstream` and stream operators, eg `out << "name: " << name << ", age: " << age;`. Since C++20 and VS 2019 you can [use stf::format](https://devblogs.microsoft.com/cppblog/format-in-visual-studio-2019-version-16-10/) There are explicit Unicode types and literals, described in [String Characters and Literals](https://learn.microsoft.com/en-us/cpp/cpp/string-and-character-literals-cpp?view=msvc-170) – Panagiotis Kanavos Apr 07 '23 at 11:42
  • Using C++ idioms and classes avoids C's overflow problems in most cases, removing the need for OS-specific calls. For the rest, there are [safe equivalents](https://learn.microsoft.com/en-us/cpp/standard-library/safe-libraries-cpp-standard-library?view=msvc-170) of the C++ functions like `basic_string::_Copy_s` instead of `basic_string::copy` – Panagiotis Kanavos Apr 07 '23 at 11:51
  • Does this answer your question? [C++ equivalent of sprintf?](https://stackoverflow.com/questions/4983092/c-equivalent-of-sprintf) – Panagiotis Kanavos Apr 07 '23 at 11:52
  • @PanagiotisKanavos Thanks for your comments however I'm just trying to figure out how to call a function when I have WCHAR working already but I'd like to know how to use a vector when using/calling a function. This is Windows-specific, so not necessary for pure C++ non-OS specific calls. I'll add a tag for Windows. – JeffR Apr 07 '23 at 11:57
  • Change:- `auto *sResult = new WCHAR[256];` -> `std::wstring sResult(256);` and `StringCchPrintfW(sResult, 256, L"this is a %s", L"test");` -> `StringCchPrintfW(&sResult[0], sResult.size(), L"this is a %s", L"test");` etc – Richard Critten Apr 07 '23 at 12:09
  • @JeffR there's no reason to write such code on Windows since the late 1990s. I linked to Visual Studio's own documentation. I've actually written MFC code back then and got rid of LPTSTRs as soon as I could, once better versions of MFC and ATL came out – Panagiotis Kanavos Apr 07 '23 at 12:14

1 Answers1

2

Rewrite your function like this

void GetText(WCHAR *sText, DWORD dwTextSize)
{
    StringCchPrintfW(sText, dwTextSize, L"this is a %s", L"test");
}

Use it like this

WCHAR *sResult = new WCHAR[256];
GetText(sResult, 256);
delete[] sResult;

std::vector<WCHAR> sResult2(256);
GetText(sResult2.data(), 256);

auto sResult3 = std::make_unique<WCHAR[]>(256);
GetText(sResult3.get(), 256);    

Your function had a unnecessary level of indirection (WCHAR** instead of WCHAR*). Once that is removed the function becomes trivial to use with all three of your data types.

john
  • 85,011
  • 4
  • 57
  • 81