使用 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
是一个悬挂指针。 wostringstream
的str()
函数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::wstring
、wchar_t
和适当的函数,让您的生活更轻松。
我已经声明了以下方法来将整数转换为 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
是一个悬挂指针。 wostringstream
的str()
函数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::wstring
、wchar_t
和适当的函数,让您的生活更轻松。