C++ sprintf 一个 LPCWSTR 变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3037850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:52:25  来源:igfitidea点击:

sprintf an LPCWSTR variable

c++windows

提问by Julio

I'm trying to debug print an LPCWSTRstring, but I get a problem during the sprintfpush in the buffer, because it retrieves only the first character from the string.

我正在尝试调试打印一个LPCWSTR字符串,但在sprintf推送缓冲区期间出现问题,因为它仅从字符串中检索第一个字符。

Here is the code:

这是代码:

HANDLE WINAPI hookedCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) {
    char buffer[1024];
    sprintf_s(buffer, 1024, "CreateFileW: %s", lpFileName);
    OutputDebugString(buffer); 
    return trueCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, dwCreationDisposition, hTemplateFile);
}

For example I get CreateFileW: Cor CreateFileW: \.

例如我得到CreateFileW: CCreateFileW: \

How do I properly push it into the buffer?

我如何正确地将它推入缓冲区?

Thank you.

谢谢你。

回答by Hans Passant

You need to tell sprintf() that you pass a wide character string. Use the %ls specifier:

您需要告诉 sprintf() 您传递了一个宽字符串。使用 %ls 说明符:

 sprintf_s(buffer, 1024, "CreateFileW: %ls", lpFileName);

Do note how unproductive this is. Your code runs on a Unicode operating system. It must convert your char[] string back to a wide string before it can send it to the debugger. That's just wasted CPU cycles with a significant risk of data loss to boot. When you are in Rome, act like a Roman and use wchar_t + wsprintf(). And #define UNICODE so you'll automatically call the fast OutputDebugStringW(), the one that doesn't have to convert the string. The point of using C++ is to write fastcode, intentionally making is slow is pointless.

请注意这是多么徒劳。您的代码在 Unicode 操作系统上运行。它必须将您的 char[] 字符串转换回宽字符串,然后才能将其发送到调试器。这只是浪费了 CPU 周期,并且存在启动时数据丢失的重大风险。当你在罗马时,表现得像个罗马人,使用 wchar_t + wsprintf()。和#define UNICODE 这样你就可以自动调用快速的OutputDebugStringW(),它不需要转换字符串。用C++的重点是写快的代码,刻意写慢是没有意义的。

回答by shoosh

Use swprintf_swhich is the version of sprintf_s which is designed for wide-character strings.

使用swprintf_s,这是专为宽字符串设计的 sprintf_s 版本。

You'll also need an array of wchar_tinstead of charand to use OutputDebugStringW()

您还需要一个数组wchar_t代替char和使用OutputDebugStringW()

Also, note you that swprintf_wmight not be entierly what you want to call. If it encounters a string that is longer than the size you give it, it executes some sort of assertion. I suggest you test this situation specifically.

另外,请注意,这swprintf_w可能不是您想要调用的。如果它遇到一个比你给它的大小更长的字符串,它会执行某种断言。我建议你专门测试一下这种情况。

回答by Ofek Shilon

Unless you have a concrete reason to target unicode in this single function (and not, say, in your entire project), it might be wise to use charset-agnostic macros wherever possible:

除非你有一个具体的理由在这个单一的函数中(而不是在你的整个项目中)以 unicode 为目标,否则尽可能使用与字符集无关的宏可能是明智的:

HANDLE WINAPI hookedCreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) {
 TCHAR buffer[1024];
 _stprintf_s(buffer, 1024, _T("CreateFileW: %s"), lpFileName);
 OutputDebugString(buffer); 
 return trueCreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwFlagsAndAttributes, dwCreationDisposition, hTemplateFile);
}