使用 sstream 将 int 转换为 LPCTSTR 时的奇怪结果

Strange Results when converting int to LPCTSTR with sstream

我已经声明了以下方法来将整数转换为 LPCTSTR 以便在 MFC 应用程序中使用。

LPCTSTR CTCPServerDlg::Int32ToLPCTSTR(int i32) {
    std::wostringstream ss;
    ss << i32;
    LPCTSTR res = ss.str().c_str();
    MessageBox(ss.str().c_str()); // Correctly shows value.
    MessageBox(res); // Nothing shown.
    return res;
}

如上所述,第一个消息框正确显示了我传递给 i32 参数的整数。第二个消息框什么都不显示(或者我认为是不可见字符)。像这样调用函数时:

MessageBox(Int32ToLPCTSTR(3));

我得到一些奇怪的字符。我认为这是中国的象征。我知道 Windows 中不同类型的 Unicode 和 ANSI 可能会让我们中最好的人感到困惑,但是 ss.str().c_str() 的 return 值应该正确分配给我声明的 LPCTSTR res 变量对吗?此外,当试图将创建的 LPCTSTR 插入到 CEdit 控件中时,我得到了更多的未知汉字,与以前完全不同。

抱歉,如果我是愚蠢的,帮助赞赏!

ss.str()返回的字符串按值返回,如果你不存储它那么它是临时的,一旦表达式完成就会被破坏,给你留下一个指向不再存在的字符串的指针。当您尝试取消引用该流浪指针时,这当然会导致 undefined behavior

res 是一个悬挂指针。 wostringstreamstr()函数return是一个新的std::wstring值。这意味着它是一个临时的。

std::wstring函数c_str()return是一个指向字符串内部缓冲区的指针。该指针仅在字符串本身保持有效(且未修改)时才有效。

这意味着 res 在其初始化结束后立即变为悬空状态。

您的函数的整个界面看起来有缺陷。要 return a LPCTSTR,它必须为 returned 字符串分配内存。但这意味着您将 returning 一个指向动态分配内存的原始指针,这会导致泄漏、双重删除错误等。只需将您的函数更改为 return a std::wstring (或 _tstring 如果您真的 想继续使用 TCHAR)。然后,您可以在必要时通过调用 c_str().

从中获取 LPCTSTR

更好的是,我建议您完全放弃使用 TCHAR。您曾经 打算为单字节字符串或多字节字符串构建您的应用程序吗?我假设不会,在这种情况下,您可以简单地使用 std::wstringwchar_t 和适当的函数,让您的生活更轻松。