WinMain参数

3

我的问题是参数只检索每个参数的第一个字母,我不知道为什么...有人能详细说明一下吗?

#include <Windows.h>
#include <string>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hpInstance, LPSTR nCmdLine, int iCmdShow){

LPWSTR *szArglist;
    int nArgs = 0;
    szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
    std::string a;
    for(int i=0; i<nArgs; i++){
        a += (LPCSTR)szArglist[i];
    }

    MessageBox(NULL, (LPCSTR)a.c_str(), (LPCSTR)a.c_str(), MB_OK);

    LocalFree(szArglist);
return 0;
}

我认为问题出在 CommandLineToArgvW(GetCommandLineW(), &nArgs); 这行代码。


2
这就是为什么 C 强制类型转换很糟糕的原因。如果你遇到编译器错误,不要本能地添加强制类型转换。使用 std::wstring,并且可以通过将 a 初始化为 GetCommandLineW 并删除空格来替换 for 循环。 - chris
1
详细阐述为什么C语言的类型转换是有害的,一个宽字符可能由位序列 0100000000000000 表示,而相同的位序列由ANSI字符表示为两个字符 01000000 00000000。现在它是一个字符的空结束字符串。 - Chris Cooper
std::wstringstd::string并没有什么不同。它们都是使用不同字符类型的typedefs。 - chris
我相信你可以使用std::wstring代替std::string,使用LPCTSTR代替LPCSTR。 - Chris Cooper
就我理解的情况,假设您有不采纳我的答案的充分理由(例如这是存根测试代码,您将对参数数组执行某些有趣的操作),您的问题是您正在使用std::stringLPCWSTR一起使用,这是行不通的。 LPCWSTRstd::wstring配合使用,LPCSTRstd::string配合使用,应避免使用LPCTSTR,以免发疯。 - zwol
显示剩余3条评论
2个回答

3

LPWSTR 被定义为 wchar_t *szArglist 是由一组wchar_t * 组成的数组。宽字符由2个字节表示而不是1个字节,所以一个字符可能被表示为:

0x0038 0x0000

然而,如果你取这些字节并且说“嘿,假装我是一个char *,这看起来像一个C风格的只有一个字符(0x0038)的字符串,因为第二个字符(0x0000)是空的,在C风格的字符串中表示字符串的结尾。

你遇到的问题是试图将宽字符(wchar_t)适配到非宽字符(char)字符串中,这是一个更加复杂的操作。

解决方法:要么在整个项目中都使用wstring/wchar_t (对应于LPWSTR/LPCWSTR),或者在整个项目中都使用string/char (对应于LPSTR和LPCSTR,我相信)。注意,你的项目设置中的"使用Unicode"应该与你的决定相匹配。尽量不要混用这些!


0

这不应该只是

int WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE hpInstance, LPSTR nCmdLine, int iCmdShow)
{
    MessageBoxA(NULL, nCmdLine, nCmdLine, MB_OK);
    return 0;
}

或者

int WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE hpInstance, LPSTR nCmdLine, int iCmdShow)
{
    MessageBoxW(NULL, GetCommandLineW(), GetCommandLineW(), MB_OK);
    return 0;
}

?


哦,哇!!!你太棒了。我真的不知道你可以直接调用它们!你是个大佬。 - user2588062
你所说的“它们”是指MessageBox的A和W形式吗?是的,几乎所有接受字符串参数的Windows API函数都有这两种形式,现代最佳编码实践是始终使用它们。未经限定的版本仅用于向后兼容旧代码。 - zwol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接