【问题标题】:C++: convert LPTSTR to char array [duplicate]C ++:将LPTSTR转换为char数组[重复]
【发布时间】:2012-05-21 09:10:39
【问题描述】:

可能重复:
Convert lptstr to char*

我需要将LPTSTR p 转换为CHAR ch[]。我是 C++ 新手。

#include "stdafx.h"
#define _WIN32_IE 0x500
#include <shlobj.h>
#include <atlstr.h>
#include <iostream>
#include <Strsafe.h>

using namespace std;

int main(){
    int a;
    string res;
    CString path;
    char ch[MAX_PATH];
    LPTSTR p = path.GetBuffer(MAX_PATH);
    HRESULT hr = SHGetFolderPath(NULL,CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, p);

/* some operation with P and CH */

    if(SUCCEEDED(hr))
    { /* succeeded */
        cout << ch;
    } /* succeeded */
    else
    { /* failed */
        cout << "error";
    } /* failed */
    cin >> a;
    return 0;
}

提前致谢。

【问题讨论】:

标签: c++ c visual-studio lptstr


【解决方案1】:

LPTSTR 是一个(非常量)TCHAR 字符串。取决于它是否显示为 Unicode。如果不是 Unicode,LPTSTR 是 char*,如果是,则为 w_char*。

如果您使用的是非 Unicode 字符串,LPTSTR 只是一个 char*,否则:

size_t size = wcstombs(NULL, p, 0);
char* CharStr = new char[size + 1];
wcstombs( CharStr, p, size + 1 );

此外,此链接可以提供帮助:

Convert lptstr to char*

【讨论】:

  • 我有错误 23 错误 C2664: 'wcstombs' : 无法将参数 2 从 'LPTSTR' 转换为 'const wchar_t *'
  • 你有非 Unicode 字符串,在这种情况下你不需要使用 wcstombs()。只需使用简单的转换为 char*。
  • +1 LPTSTR is char* if not Unicode, or w_char* if so. 过了很长一段时间,我才发现这一点清晰。在kerwal.com/home/charwchartwchartcharomgwtftmi 上快速、有用的总结。
【解决方案2】:

LPTSTR 表示TCHAR*(扩展那些 Win32 首字母缩写词 typedef 可以更容易理解它们)。 TCHAR 在 ANSI/MBCS 版本中扩展为 char,在 Unicode 版本中扩展为 wchar_t(为了更好的国际化支持,这在当今应该是默认设置)。

此表总结了 ANSI/MBCS 和 Unicode 版本中的 TCHAR 扩展

          |   ANSI/MBCS    |     Unicode
  --------+----------------+-----------------
  TCHAR   |     char       |     wchar_t
  LPTSTR  |     char*      |     wchar_t*
  LPCTSTR |  const char*   |  const wchar_t*

因此,在 ANSI/MBCS 构建中,LPTSTR 扩展为 char*;在 Unicode 构建中,它扩展为 wchar_t*

char ch[MAX_PATH] 是 ANSI 和 Unicode 版本中的 char 数组。

如果你想从TCHAR字符串(LPTSTR)转换为ANSI/MBCS字符串(char-based),你可以使用ATL string conversion helpers,例如:

LPTSTR psz;   // TCHAR* pointing to something valid    
CT2A ch(psz); // convert from TCHAR string to char string

(另请注意,在您的原始代码中,您应该调用CString::ReleaseBuffer(),这是CString::GetBuffer() 的对称。)

示例代码如下:

// Include ATL headers to use string conversion helpers
#include <atlbase.h>
#include <atlconv.h>
...

LPTSTR psz = path.GetBuffer(MAX_PATH);
HRESULT hr = SHGetFolderPath(NULL,CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, psz);
path.ReleaseBuffer();
if (FAILED(hr))
{
  // handle error
  ...
}

// Convert from TCHAR string (CString path) to char string.
CT2A ch(path);

// Use ch...
cout << static_cast<const char*>(ch) << endl;

另请注意,从 Unicode 到 ANSI 的转换可能是有损的

【讨论】:

    【解决方案3】:

    首先,您定义了char* ch[MAX_PATH] 而不是char ch[MAX_PATH]

    关于您的问题,如果是 unicode,则 LPTSTR(指向 TCHAR 字符串的长指针)等效于 LPWSTR(即 w_char*),如果是 unicode,则等效于 LPSTR(char*)不是。您可以使用this link 了解每种情况下的转化情况。

    编辑:切入正题,下面是一些代码:

    if (sizeof(TCHAR) == sizeof(char))  // String is non-unicode
        strcpy(ch, (char*)(p));       
    else                                // String is unicode
        wcstombs(ch, p, MAX_PATH);
    

    编辑 2:在 Windows 中,我建议使用 TCHAR 而不是 char。它会让你不那么头疼。

    编辑 3:附带说明,如果您想防止 Visual Studio 向您发出关于不安全函数的警告,您可以在代码的最开头添加如下内容:

    #ifdef _MSC_VER
    #define _CRT_SECURE_NO_WARNINGS
    #endif
    

    【讨论】:

    • 你能写一些代码吗?
    • @Sasha 我给你的参考应该已经涵盖了它,但可以肯定。我在答案中添加了示例代码。
    • 我认为 ATL 转换助手使代码更容易。此外,如果您想检查 Unicode 与 ANSI/MBCS 构建,我更喜欢使用预处理器 在编译时 使用 UNICODE/_UNICODE 预处理器宏(它们是 #define' d 在 Unicode 版本中),而不是在运行时使用 if(sizeof(TCHAR) == sizeof(char)) ... 进行检查。
    • +1 用于编译时检查 :)
    • 如果安全模板重载 (msdn.microsoft.com/en-us/library/ms175759%28v=vs.100%29.aspx) 通常最好尝试使足够多的警告静音,而不是完全禁用警告。毕竟这些警告的存在是有原因的。
    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 2011-06-08
    • 2021-05-03
    • 1970-01-01
    相关资源
    最近更新 更多