【问题标题】:How to print array of LPCTSTR in c++?如何在 C++ 中打印 LPCTSTR 数组?
【发布时间】:2015-02-12 15:32:06
【问题描述】:

如何打印 LPCTSTR 数组

例子

LPCTSTR pszValueNames[] = { L"partnerID", L"partnerSubID", L"transactionID" };

for (int i = 0; i < (sizeof(pszValueNames) / sizeof(LPCWSTR)); i++)
{
    cout << (*pszValueNames[i]) << endl;
}

上面给出了一些不是真正的 lpctstr 值的数字。 当我使用 wchar_t* 和所有其他基本类型时,它会产生很好的价值。

【问题讨论】:

  • 在我看来,您只需要去掉 * 行中的 * 取消引用运算符
  • 然后我只得到地址
  • 这里的信息看起来很有用:cplusplus.com/forum/general/56526
  • 不要将 L 与 LPCTSTR 一起使用。将 L 与 LPCWSTR 一起使用。将 _T() 宏与 LPCTSTR 一起使用,它将是 L 或无操作,以匹配您的设置的任何 LPCTSTR。 LPCTSTR 在 Unicode 版本上是 LPCWSTR,在“ANSI”版本上是 LPCSTR。

标签: c++ arrays cout


【解决方案1】:

打印地址的原因是std::coutstd::string 一起使用,char 是基于char 的。 LPCWSTR 是宽字符串指针类型,cout 不知道如何将宽字符串“显示为字符串”。

您应该使用std::wcout 来处理宽字符串。

std::wcout &lt;&lt; pszValueNames[i] &lt;&lt; std::endl;

此外,您对LPCTSTR 的使用不正确,即使您的程序可以运行。如果您知道您使用的是宽字符串,请在您会使用LPCTSTR 的任何地方指定LPCWSTR。原因是 LPCTSTR 不一定是宽字符串指针类型,具体取决于您使用的构建类型(MBCS 或 Unicode)。

所以简而言之,你的字符串指针声明是不同字符串类型的大杂烩,其中一些函数可能工作(如果LPCTSTR 是一个非宽字符指针),而其他字符串处理函数不会工作。

基本上,如果您要使用LPCTSTRLPTSTR,那么处理字符串或字符串指针类型的所有代码都应使用“构建中性”类型,即使用LPCTSTRTCHARLPTSTR_T() 等。如果您从 MBCS 构建转到 Unicode 构建(无论出于何种原因,反之亦然),这些类型将无缝更改。

另一方面,如果您知道构建只会是Unicode,那么应该在整个程序中使用LPCWSTRLPWSTR。相反,如果您知道并且可以保证构建只会是 MBCS,则在您的程序中使用 LPCSTRLPSTR

最好的办法是在整个应用程序中使用构建中性类型(LPCTSTR 等),或者将所有这些类型更改为宽字符串类型(LPCWSTR 等)。如今,MBCS 构建变得非常少见,因此不妨开始使用宽字符串类型进行开发,并且仅当您与依赖于基于 char 的字符串的其他函数交互时,才在应用程序中使用 char 字符串类型。

【讨论】:

  • 如果必须使用 LPCTSTR,请在文字周围使用 _T() 宏而不是 L。它被定义为 L 的适当使用,具体取决于 LPCTSTR 是什么。 Google for LPCTSTR 了解更多信息。
【解决方案2】:

两个问题。首先,您正在迭代错误的大小:

for (int i = 0; i < (sizeof(pszValueNames) / sizeof(LPCWSTR)); i++)
//                                                  ^^^^^^^

应该是LPCTSTR。或者,为了避免这种错误,只需*pszValueNames。或者可能反过来,LPCWSTR 是正确的类型,但您将数组声明为 LPCTSTR

其次:

cout << (*pszValueNames[i]) << endl;

这将取消对ith 字符串的引用——这将只打印第一个字符。要打印整个字符串,您不需要取消引用。此外,您需要使用wcout,因为cout 不适用于wchar_t

wcout << pszValueNames[i] << endl;

【讨论】:

  • 不,cout 不能与 wchar_t 一起使用,而 tchar 与 ops 设置一起使用。
  • @Barry 如何遍历 *pszValueNames?
【解决方案3】:

std::wcout 已经提到过,但我想补充一点,这是一个很好的例子,说明了 C++11 功能如何改进遗留或基于 C 的代码——如果你可以使用 C++11 编译器,就是这样。

在 C++11 中,您可以这样编写循环:

for (auto const &name : pszValueNames)
{
    std::wcout << name << std::endl;
}

不再需要担心sizeof 或取消引用问题。如果您稍后将数组更改为 std::array&lt;std::wstring&gt;std::vector&lt;std::wstring&gt;std::set&lt;std::wstring&gt;,则根本不需要修改循环(容器的元素类型只需保持与 std::wcout 兼容)。


编辑:制作代码示例使用const &amp;

【讨论】:

    【解决方案4】:

    [] 操作符在指向的 mem 之后访问内存的 index*sizeof(type) 部分。值,并且此运算符接受一个指针。你不需要 * 那里... *pszValue 是取消引用,真的,但这是在这里隐式完成的......所以你实际上是在取消引用一个值......

    引用 MSDN:“通常,postfix-expression 表示的值是一个指针值,例如数组标识符,而 expression 是一个整数值(包括枚举类型)。但是,在语法上只需要一个一个表达式是指针类型,另一个是整数类型。"

    见 [] 运算符here

    【讨论】:

      猜你喜欢
      • 2021-05-26
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 2020-05-30
      • 2012-08-31
      • 2013-09-23
      • 1970-01-01
      相关资源
      最近更新 更多