Windows API和字符串连接[重复]

Posted

技术标签:

【中文标题】Windows API和字符串连接[重复]【英文标题】:Windows API and String concatenation [duplicate] 【发布时间】:2015-04-07 18:28:03 【问题描述】:

我对 C++ 和 Windows API(来自 Java 背景)比较陌生,我只是在玩 Windows API 调用 MessageBox 和其他简单函数,直到我尝试从自定义传递连接字符串函数到MessageBox,我注意到生成的窗口中有一个奇怪的输出。

这是可疑函数:

const char* addFoo(const char* strInput)

    return ("foo-" + std::string(strInput)).c_str();

它只是返回原始输入,并在前面添加foo-。 (我希望我没有做任何令人难以置信的错误)

然后,我在 main 中对 MessageBox 进行两次调用,首先不调用该函数,而是即时进行所有计算,然后调用该函数:

const char* a = "bar";
MessageBox(NULL, ("foo-" + std::string(a)).c_str(), "The Foobar Experiment", MB_OK);
MessageBox(NULL, addFoo(a), "The Foobar Experiment", MB_OK);

这是我通过动态连接字符串得到的结果(案例 1):

调用函数addFoo得到的结果(案例2):

有谁知道为什么我使用 addFoo 函数在生成的窗口上得到这些不可读的字符?提前致谢,很抱歉发了这么长的帖子。

【问题讨论】:

UB。当 MessageBox 使用指向 char 数组的指针时,您的 std::string 不再存在(addFoo() 的本地)。 coming from a Java background 这意味着在编写 C++ 代码时不使用 Java 作为指南。 【参考方案1】:

您的代码中有两个根本错误的地方,一个与 C++ 相关,另一个与 Windows 相关。

首先,您要返回一个指向本地实体的指针,即c_str() 的返回值,它是一个指针。返回指向局部变量的指针是未定义的行为。你想要做的是返回一个字符串,而不是一个指针。在 C++ 中,有一些字符串类型,例如 std::stringstd::wstring,它们实现了正确的复制语义,这些语义需要让对象安全返回而不会出错。

#include <string>
std::string addFoo(const char* strInput)

    return "foo-" + std::string(strInput);


您的代码的第二个问题是,在 Windows 世界中,就字符类型而言,您基本上有两种类型的应用程序。您有MBCS 应用程序和Unicode 应用程序。

如果您构建了一个 Unicode 应用程序,您对 MessageBox 的调用将不会成功编译,因为 MessageBox 采用宽字符串,而不是基于字符的字符串。在这种情况下,要使用的正确字符串类型是std::wstring

您很可能构建了一个MBCS 应用程序,这在当今时代变得非常罕见。

【讨论】:

感谢您的详细回答和您为此付出的努力。祝你有个愉快的夜晚【参考方案2】:
const char* addFoo(const char* strInput)

    return ("foo-" + std::string(strInput)).c_str();

这会返回一个指向本地临时字符串的指针,当你的消息框显示时它的内存就会被释放。

在您的情况下将其替换为 std::string

std::string addFoo(const char* strInput)

    return std::string("foo-") + strInput; // not sure about the syntax here

然后,std::string 对象正确地管理其内存并使字符串指针保持活动的时间足够长,以便消息框显示它。您需要包含 &lt;string&gt; 才能定义它。

然后,您可以使用:

std::string temp = addFoo( a );
MessageBox(NULL, temp.c_str(), "The Foobar Experiment", MB_OK);

【讨论】:

CString 在 Windows API 世界中不存在。如果有的话,一个 C++ 字符串类型,例如 std::stringstd::wstring 好的,把它改成std::string,我以为CString一直都在,但你说得对,它可能只是MFC的一部分。 感谢您的详细解答。祝你有个愉快的夜晚

以上是关于Windows API和字符串连接[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用连接字符串连接到 odbc

C#中如何设置字符串连接到MySQL数据库?

为啥在字符串连接上使用 os.path.join?

Spark - 将每个分区的字符串连接到单个字符串

播放 wav 文件,将字符串连接到调用文件

如何通过Prolog将字符串连接到列表中的多个元素?