如何在 C++ 中打印 LPCTSTR 数组?
How to print array of LPCTSTR in c++?
如何打印 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* 和所有其他基本类型时,它会吐出很好的值。
您打印地址的原因是 std::cout
与基于 char
的 std::string
一起使用。 LPCWSTR
是宽字符串指针类型,cout
不知道如何显示宽字符串 "as strings".
您应该使用 std::wcout
来处理宽字符串。
std::wcout << pszValueNames[i] << std::endl
;
此外,您对 LPCTSTR
的用法不正确,即使您的程序可能有效。如果您知道自己使用的是宽字符串,请在本应使用 LPCTSTR
的任何地方指定 LPCWSTR
。原因是 LPCTSTR
不一定是宽字符串指针类型,具体取决于您使用的构建类型(MBCS 或 Unicode)。
所以简而言之,您的字符串指针声明是不同字符串类型的大杂烩,其中一些函数可能起作用(如果 LPCTSTR
是非宽字符指针),而其他字符串处理功能将不起作用。
基本上,如果您要使用 LPCTSTR
或 LPTSTR
,那么所有处理字符串或字符串指针类型的代码都应使用 "build-neutral" 类型,即使用 LPCTSTR
、TCHAR
、LPTSTR
、_T()
等。如果您从 MBCS 构建转到 Unicode 构建(无论出于何种原因反之亦然),这些类型将无缝更改.
另一方面,如果您知道构建只会是 Unicode
,那么应该在整个程序中使用 LPCWSTR
和 LPWSTR
。相反,如果您知道并且可以保证构建只会是 MBCS,那么在您的程序中使用 LPCSTR
和 LPSTR
。
最好的办法是在整个应用程序中使用构建中性类型(LPCTSTR
等),或者将所有这些更改为宽字符串类型(LPCWSTR
等)。 ).如今 MBCS 构建变得非常罕见,因此不妨开始使用宽字符串类型进行开发,并且当您连接到依赖于 char
的其他函数时,仅在您的应用程序中使用 char
字符串类型基于字符串。
两个问题。首先,您迭代了错误的大小:
for (int i = 0; i < (sizeof(pszValueNames) / sizeof(LPCWSTR)); i++)
// ^^^^^^^
应该是LPCTSTR
。或者,为了避免这种错误,只需 *pszValueNames
。或者可能相反,LPCWSTR
是正确的类型,但您将数组声明为 LPCTSTR
。
其次:
cout << (*pszValueNames[i]) << endl;
这将取消引用第 i
个字符串 - 它将仅打印第一个字符。要打印整个字符串,您不需要取消引用。此外,您需要使用 wcout
,因为 cout
不适用于 wchar_t
:
wcout << pszValueNames[i] << endl;
[]运算符访问指向的mem之后的内存的index*sizeof(type)部分。值,并且此运算符采用指针。您不需要那里的 *... *pszValue 正在取消引用,是的,但这是隐式完成的...所以您实际上是在取消引用一个值...
引自 MSDN:"Usually, the value represented by postfix-expression is a pointer value, such as an array identifier, and expression is an integral value (including enumerated types). However, all that is required syntactically is that one of the expressions be of pointer type and the other be of integral type."
参见[]运算符here
std::wcout
已经提到,但我想补充一点,这是一个很好的例子,说明 C++11 功能如何改进遗留或基于 C 的代码——如果你可以使用 C+ +11编译器,即
在 C++11 中,您可以这样编写循环:
for (auto const &name : pszValueNames)
{
std::wcout << name << std::endl;
}
无需再担心 sizeof
或取消引用问题。如果您稍后将数组更改为 std::array<std::wstring>
或 std::vector<std::wstring>
或 std::set<std::wstring>
之类的内容,则根本不必修改循环(容器的元素类型只需要与 std::wcout
).
保持兼容
编辑:使代码示例使用 const &
如何打印 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* 和所有其他基本类型时,它会吐出很好的值。
您打印地址的原因是 std::cout
与基于 char
的 std::string
一起使用。 LPCWSTR
是宽字符串指针类型,cout
不知道如何显示宽字符串 "as strings".
您应该使用 std::wcout
来处理宽字符串。
std::wcout << pszValueNames[i] << std::endl
;
此外,您对 LPCTSTR
的用法不正确,即使您的程序可能有效。如果您知道自己使用的是宽字符串,请在本应使用 LPCTSTR
的任何地方指定 LPCWSTR
。原因是 LPCTSTR
不一定是宽字符串指针类型,具体取决于您使用的构建类型(MBCS 或 Unicode)。
所以简而言之,您的字符串指针声明是不同字符串类型的大杂烩,其中一些函数可能起作用(如果 LPCTSTR
是非宽字符指针),而其他字符串处理功能将不起作用。
基本上,如果您要使用 LPCTSTR
或 LPTSTR
,那么所有处理字符串或字符串指针类型的代码都应使用 "build-neutral" 类型,即使用 LPCTSTR
、TCHAR
、LPTSTR
、_T()
等。如果您从 MBCS 构建转到 Unicode 构建(无论出于何种原因反之亦然),这些类型将无缝更改.
另一方面,如果您知道构建只会是 Unicode
,那么应该在整个程序中使用 LPCWSTR
和 LPWSTR
。相反,如果您知道并且可以保证构建只会是 MBCS,那么在您的程序中使用 LPCSTR
和 LPSTR
。
最好的办法是在整个应用程序中使用构建中性类型(LPCTSTR
等),或者将所有这些更改为宽字符串类型(LPCWSTR
等)。 ).如今 MBCS 构建变得非常罕见,因此不妨开始使用宽字符串类型进行开发,并且当您连接到依赖于 char
的其他函数时,仅在您的应用程序中使用 char
字符串类型基于字符串。
两个问题。首先,您迭代了错误的大小:
for (int i = 0; i < (sizeof(pszValueNames) / sizeof(LPCWSTR)); i++)
// ^^^^^^^
应该是LPCTSTR
。或者,为了避免这种错误,只需 *pszValueNames
。或者可能相反,LPCWSTR
是正确的类型,但您将数组声明为 LPCTSTR
。
其次:
cout << (*pszValueNames[i]) << endl;
这将取消引用第 i
个字符串 - 它将仅打印第一个字符。要打印整个字符串,您不需要取消引用。此外,您需要使用 wcout
,因为 cout
不适用于 wchar_t
:
wcout << pszValueNames[i] << endl;
[]运算符访问指向的mem之后的内存的index*sizeof(type)部分。值,并且此运算符采用指针。您不需要那里的 *... *pszValue 正在取消引用,是的,但这是隐式完成的...所以您实际上是在取消引用一个值...
引自 MSDN:"Usually, the value represented by postfix-expression is a pointer value, such as an array identifier, and expression is an integral value (including enumerated types). However, all that is required syntactically is that one of the expressions be of pointer type and the other be of integral type."
参见[]运算符here
std::wcout
已经提到,但我想补充一点,这是一个很好的例子,说明 C++11 功能如何改进遗留或基于 C 的代码——如果你可以使用 C+ +11编译器,即
在 C++11 中,您可以这样编写循环:
for (auto const &name : pszValueNames)
{
std::wcout << name << std::endl;
}
无需再担心 sizeof
或取消引用问题。如果您稍后将数组更改为 std::array<std::wstring>
或 std::vector<std::wstring>
或 std::set<std::wstring>
之类的内容,则根本不必修改循环(容器的元素类型只需要与 std::wcout
).
编辑:使代码示例使用 const &