【问题标题】:char array to LPCTSTR conversion in cc中的char数组到LPCTSTR的转换
【发布时间】:2010-11-01 20:55:05
【问题描述】:

有人知道如何在 c 中将 char 数组转换为 LPCTSTR 吗?

编辑:

为了获得更多参考,我需要将一个整数添加到一个字符串中,然后将该字符串转换为 LPCTSTR 作为 windows 函数 CreateFile() 的第一个参数。

这是我目前使用的硬编码示例,但我需要能够传入任何数字以用作端口号。

CreateFile(_T("\\\\.\\COM11")... //hardcoded for com port 11

这是我尝试过的几件事,我相信其中包括对本文接下来的 2 个答案的以下建议。不幸的是,它们不起作用。如果有人能指出我做错了什么并可能解决我的问题,我将不胜感激。

所有这些示例都假定 portNum 是一个已分配有效值的 int

1

char portName[12] = { 0 };

sprintf_s( portName, sizeof( portName ), "\\\\.\\COM%i", portNum );

CreateFile(portName...

我还尝试了使用 LPCSTR 案例的 #1 来证明它的价值...

2

LPCSTR SomeFunction(LPCSTR aString) {
    return aString;
}

main() {

char portName[12] = { 0 };
sprintf_s( portName, sizeof( portName ), "\\\\.\\COM%i", portNum );

LPCSTR lpPortName = SomeFunction(portName);

CreateFile(lpPortName...

3

const char * portName = "";
sprintf_s( portName, sizeof( portName ), "\\\\.\\COM%i", portNum );

LPCSTR lpPortName = portName;

CreateFile(lpPortName...

【问题讨论】:

    标签: c windows arrays char


    【解决方案1】:

    您可以将 char 数组隐式转换为 LPCSTR 而无需任何强制转换:

    void SomeFunction(LPCSTR aString);
    ...
    char myArray[] = "hello, world!";
    SomeFunction(myArray);
    

    LPCSTR 是 Windows 类型定义,用于指向常量字符串的长指针。早在 Win16 编程的黑暗时期,就有不同类型的指针:near 指针和 far 指针,有时也称为 short 和 long 指针。 Near 指针只能指向由 x86 段寄存器之一确定的 64KB 内存段。远指针可以指向任何东西。现在在带有虚拟内存的 Win32 中,不需要近指针——所有指针都是长指针。

    所以,LPSTRchar * 的 typedef,或指向字符串的指针。 LPCSTRconst 版本,即它是 const char * 的 typedef。在 C 中,数组衰减为指向其第一个元素的指针,因此 char[] 衰减为 char*。最后,任何类型的“指向 T 的指针”(对于任何类型 T)都可以隐式转换为“指向 const T 的指针”。因此,结合这三个事实,我们可以看到我们可以将char[] 隐式转换为LPCSTR


    作为对您的编辑的回应,我猜您正在编译一个 Unicode 应用程序。如果您仔细查看documentation for CreateFile(),您会注意到文件名参数实际上是LPCTSTR,而不是LPCSTR(注意T)。

    对于几乎所有接受某种字符串类型参数的 Win32 函数(可能是间接的,即作为作为参数传递的结构的成员),该函数实际上有两个版本:一个接受 8 位 ANSI字符串,一种采用 16 位宽字符串。要获取实际的函数名称,您需要在函数名称后附加 AW。因此,CreateFile() 的 ANSI 版本命名为 CreateFileA(),宽字符版本命名为 CreateFileW()。根据您是否在启用 Unicode 的情况下进行编译(即是否定义了预处理器符号 _UNICODE),符号 CreateFile#defined 到 CreateFileACreateFileW(视情况而定),同样适用于具有 ANSI 和宽字符版本的所有其他函数。

    同理,TCHAR 类型是 typedefed 到 charwchar_t,这取决于是否启用了 Unicode,而 LPCTSTRtypedefed 到指向 @ 的指针987654354@.

    因此,为了使您的代码正确,您应该将正在使用的字符串替换为TCHAR 字符串,并使用sprintf_s_stprintf_s 的类型通用版本:

    TCHAR portName[32];
    _stprintf_s(portName, sizeof(portName)/sizeof(TCHAR), _T("\\\\.\\COM%d"), portNum);
    CreateFile(portName, ...);
    

    或者,您可以显式使用所有内容的 ANSI 或宽字符版本:

    // Use ANSI
    char portName[32];
    sprintf_s(portName, sizeof(portName), "\\\\.\\COM%d", portNum);
    CreateFileA(portName, ...);
    
    // Use wide-characters
    wchar_t portName[32];
    swprintf_s(portName, sizeof(portName)/sizeof(wchar_t), L"\\\\.\\COM%d", portNum);
    CreateFileW(portName, ...);
    

    【讨论】:

    • 不幸的是,这并没有解决我的问题,尽管我添加了一个我需要完成的代码示例——你可以查看上面的代码。
    • @Schyler 您的代码中似乎没有 CreateFileA() (注意“A”)。将 CreateFile() 更改为此,它应该可以工作。
    • 转换为 LPCSTR 或 LPCTSTR?因为如果定义了 UNICODE 符号,LPCTSTR 可以是 wchar_t*。
    • 这个答案对于像我这样开始 Windows 编程的人来说真的很有帮助
    【解决方案2】:

    你的 char 数组是什么格式的?

    它是 const char[] 还是非常量?

    LPCSTR 只是“指向常量字符串的长指针”的(有点)令人困惑的 Microsoft 名称。

    LPCSTR bar = "hello";
    const char *foo = bar;
    
    const char *evil = "hello";
    LPCSTR sauron = evil;
    

    如果你需要获得一个非常量版本,你要么抛弃常量,要么复制到一个新数组。我可能更喜欢后者。变量通常是 const 是有原因的,而更改它们几乎总是不好的做法。

    【讨论】:

    • 我很确定您不必明确地将空字符放在字符串的末尾。编译器应该会自动为你做这些。
    • 感谢 Herms,它是正确的。事实上,我什至没有在我自己的代码中这样做。现已修复。
    • 想告诉我们为什么Foredecker,除了末尾的\0?不加解释就说“这不好”是没有建设性的。
    • 我能想到的唯一不好的事情是它使字符串占用的内存超出了它们的需要,因为编译器会在末尾添加一个空字符。
    • 它是非常量的——查看上面我如何尝试使用您的示例但失败的编辑。
    【解决方案3】:

    这样试试…………

    TCHAR *pcCommPort = TEXT("COM1");
    HANDLE h = CreateFile(pcCommPort,other arguments);
    

    【讨论】:

      【解决方案4】:

      你有 TCHAR 的字符串函数。例如,您可以使用接受 TCHAR 的 stprintf_s。这样,您可以使代码“独立”于 unicode 或多字节字符集。

      您的代码(变体 1)变为:

      TCHAR portName[12] = { 0 };
      
      stprintf_s( portName, sizeof( portName ) / sizeof(TCHAR), _T("\\\\.\\COM%i"), portNum );
      
      CreateFile(portName...
      

      【讨论】:

      • "sizeof( portName )," -- 哎呀。您的回答几乎教会了发帖人如何使用 TCHAR,但是一次缓冲区溢出可能会毁了您的一整天。
      • sizeof( portName ) / sizeof( TCHAR )
      【解决方案5】:
      char* filename;
      LPCTSTR ime = CA2W(filename);
      

      这是字符串转换宏,适用于我的 VS12

      【讨论】:

        【解决方案6】:

        “有人知道如何在 c 中将 char 数组转换为 LPCSTR 吗?”

        您根本不需要做任何事情。它会自动转换为该类型(初始化程序和 sizeof 除外)。

        “创建文件(端口名...”

        也许你应该告诉我们VC++在编译时给你的错误信息?

        也许您还应该告诉我们,当 Adam Rosenfield 的 whcar_t 版本不适合您时,VC++ 给了您什么错误消息?

        【讨论】:

          【解决方案7】:

          我不确定你最后是否想通了,但我遇到了同样的问题,以下对我来说效果很好:

          int  comPortNum = 5;
          char comPortName[32];
          sprintf((LPTSTR)comPortName, TEXT("\\\\.\\COM%d"), comPortNum);
          HANDLE h = CreateFile(comPortName,other arguments);
          

          【讨论】:

            【解决方案8】:

            这是一个古老的经典问题。我在 UNICODE 中使用它。

            char *pChar = "My Caption of My application";
                WCHAR wsz[512];
                swprintf(wsz, L"%S", pChar);
                SetWindowText(hWnd,         // ウィンドウまたはコントロールのハンドル
                    wsz   // タイトルまたはテキスト
                );
            

            【讨论】:

              猜你喜欢
              • 2011-09-29
              • 2012-04-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-12-15
              • 1970-01-01
              • 1970-01-01
              • 2014-01-17
              相关资源
              最近更新 更多