【问题标题】:wostringstream, Ascii, Unicode, Win32 and integer concatenation to stringwostringstream、Ascii、Unicode、Win32 和整数连接到字符串
【发布时间】:2012-08-13 07:13:19
【问题描述】:

我正在编写一个使用 Win32 API 的库,我希望能够为 ASCII 和 Unicode 编译它(宽字符是 type),并且我正在生成一个内部类名(阅读:WinAPI “类”),我将一个整数附加到一个字符串中,以便为各种 Windows 函数创建唯一的类名。

所用变量的定义:

LPCTSTR lpszClassName;    //  This is char* if ASCII, wchar_t* if Unicode.
#ifdef UNICODE
std::wostringstream Convert;
#else
std::ostringstream Convert;
#endif

有问题的函数:

void Base::MakeClassName () {
#ifdef _DEBUG_
    cerr << "Base::MakeClassName() called\n";
#endif
static int name_mod = 0;
name_mod++;
lpszClassName = TEXT("Win32WinNo");
Convert << lpszClassName << name_mod;
lpszClassName = Convert.str().c_str();

#ifdef _DEBUG_
    cerr << "Generated class name = " << lpszClassName << "\n";
#endif
}

在 ASCII 中,我得到 Generated class name = Win32WinNo1

在 Unicode 中,我得到一个十六进制值。这向我表明宽字符 wostringstream 没有做我想要的。无论哪种方式,CreateWindow 似乎都不喜欢它(程序挂起,如果我调试它,它就会崩溃。)

我不是 100% 熟悉 stringstream,根据有限的文档,它返回一个“字符串”对象,但我需要一个指向 LPCTSTR 的 C 样式字符串的指针,因此,Convert.str().c_str()。我得到的东西不能正常工作,如果我在 RegisterClass 和 CreateWindow 调用中尝试 TEXT("Win32WinNo1") ,它可以工作,但是上面返回的字符串是垃圾。

我做错了什么?我也担心它是否没有将整数附加到字符串中。 wostringstream 是否将整数转换为 wchar_t?

【问题讨论】:

  • 你可以通过定义typedef std::basic_stringstream&lt;TCHAR&gt; tstringstream等来节省很多#ifdef的混乱。它只是不适用于std::cerr,因为这是一个对象,而不是一个类型。

标签: c++ winapi unicode ascii stringstream


【解决方案1】:

ostringstream::str 返回当前与字符串流缓冲区关联的字符串对象的副本。 c_str 指向该临时字符串内部的缓冲区。只要这个临时字符串超出范围,lpszClassName 就是一个悬空指针。

这可能是您的程序崩溃/挂起的原因。

【讨论】:

  • std::wostringstream Convert 与列出的函数在同一个类中定义,所以我不确定它是如何超出范围的,这就是它在函数之外定义的原因。 (我只是没有列出整个班级,因为它会分散注意力,并且对这种情况没有用处。)
  • @Quade2002 但Convert.str() 返回的临时字符串在分配给lpszClassName 后超出范围。
  • 那么,我获取并保存的不是指针本身,而是它指向的数据超出范围?是因为我如何将它与 c_str() 链接在一起吗?
  • 明白了,基本上,我没有把它留给一个临时的字符串对象,而是明确地创建了一个并将它用作字符串流和 lpszClassName 之间的桥梁。我现在得到正确的结果,如果它是 ASCII 或 Unicode。我创建了 std::string 和 std::wstring 版本以保持所有类型正确。耶!!谢谢!
【解决方案2】:

你输出到cerr,这仍然是一个窄流。它可能会显示lpszClassName 的指针值,而不是它指向的宽字符串。

【讨论】:

  • 是的,我担心 cerr 正在做这样的事情,它正在查看类型并与 c_str() 返回的内容一起使用。我认为这是一个 C 风格的字符串,因为我的对象没有超出范围,所以指针不应该去任何地方。 (除非我在这里误解了一些东西,我可能是,这就是我有点朦胧的地方。)问题,wostringstream分配的String对象(std :: wstring)也是wchar_t类型吗?
  • 是的,宽字符串流将返回 wstringcerr 无法处理。 wcerr 会。您可能会问自己,您是否真的需要charwchar_t 编译代码。有些人已经停止这样做,而是使用 w-version 的所有内容。
【解决方案3】:

我认为您需要用 _T() 包围您的字符串文字,因此它们将是 chars 或 wchar_ts,具体取决于您的 UNICODE 设置。

例如_T("Hello World")

【讨论】:

  • 别忘了包含
  • LPCTSTR in LPCTSTR lpszClassName;正在为我做这个。取决于是否设置了 UNICODE,它定义了 windows 头文件。
  • 我相信变量的类型对字符串字面量的类型没有影响。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
  • 2012-12-04
  • 2011-11-09
  • 2012-12-26
相关资源
最近更新 更多