【问题标题】:Can't assign PathFindExtensionW output to an array of WCHAR无法将 PathFindExtensionW 输出分配给 WCHAR 数组
【发布时间】:2018-08-20 07:12:10
【问题描述】:

我想将PathFindExtensionW api 的输出分配给 WCHAR 数组。这个 api 返回一个 LPWSTR 指针。我搜索并发现将 LPWSTR 分配给 WCHAR 数组的方法如下:

WCHAR array[100] = PathFindExtensionW(,,,)

但它对我不起作用,我收到此错误:

表达式必须是可修改的左值

我使用的是 VS 2012。我的代码如下:

#include <windows.h>
#include <iostream>
#include "Shlwapi.h"

#pragma comment(lib,"shlwapi.lib")

void main(int argc, char *argv[]){

    int iToSizeB = 0;
    iToSizeB = MultiByteToWideChar(CP_UTF8, 0, argv[1], -1 , NULL, 0);

    WCHAR lpFileAddress[260] = {0};
    MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, lpFileAddress, iToSizeB);

    WCHAR lpDotPosition[260] = {0};

    //this line must be correct but I receive error
    lpDotPosition = PathFindExtensionW(lpFileAddress);

    int iToSizeW = 0;
    iToSizeW = WideCharToMultiByte(CP_UTF8, 0, lpDotPosition, -1, NULL, 0, NULL, NULL);

    CHAR lpExtension[260] = {0};
    WideCharToMultiByte(CP_UTF8, 0, lpDotPosition, -1, lpExtension, iToSizeW, NULL, NULL);

    printf("the format is:\n");
    printf(lpExtension);
    printf("\n");

    getchar();
}

这有什么问题?

感谢您的解决方案。

【问题讨论】:

  • C 不允许你分配这样的数组。如果您真的希望 lpDotPosition 成为一个数组,您需要使用一个函数将数据复制到其中(例如 strcpy 或更安全的变体)。但我怀疑你只想要一个指针,而不是一个数组 - 试试LPCWSTR lpDotPosition;
  • 我使用数组是因为我应该使用静态内存分配。因此,LPCWSTR 声明应该是动态的。我应该如何声明该功能?将指针的字符分配给数组的每个索引?
  • 我不明白为什么你需要 lpDotPosition 成为一个数组。

标签: c winapi visual-studio-2012 console-application


【解决方案1】:

您不能通过分配指针来填充数组。您必须复制数据,例如lstrcpynW()或类似功能:

LPCWSTR lpDotPosition = PathFindExtensionW(lpFileAddress);

WCHAR lpExtensionW[MAX_PATH] = {0};
lstrncpy(lpExtensionW, lpDotPosition, MAX_PATH);

但是,PathFindExtension() 只是在你传入的字符串缓冲区内返回一个指针,因此无需分配扩展的单独副本,数据已经预先分配,返回的指针将保持有效只要输入字符串有效:

#include <windows.h>
#include <iostream>
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")

int main(int argc, char *argv[])
{
    WCHAR lpFileAddress[MAX_PATH] = {0};
    int iToSizeB = MultiByteToWideChar(CP_UTF8, 0, argv[1], -1, lpFileAddress, MAX_PATH);

    LPCWSTR lpDotPosition = PathFindExtensionW(lpFileAddress);

    CHAR lpExtension[MAX_PATH] = {0};
    int iToSizeW = WideCharToMultiByte(CP_UTF8, 0, lpDotPosition, -1, lpExtension, MAX_PATH, NULL, NULL);

    printf("the format is:\n%s\n", lpExtension);

    getchar();
    return 0;
}

另一方面,不需要使用MultiByteToWideChar()WideCharToMultiByte() 来搜索char 字符串,您可以使用PathFindExtensionA() 代替:

#include <windows.h>
#include <iostream>
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")

int main(int argc, char *argv[])
{
    LPCSTR lpExtension = PathFindExtensionA(argv[1]);

    printf("the format is:\n%s\n", lpExtension);

    getchar();
    return 0;
}

【讨论】:

  • 其实代码中用MultiByteToWideChar调用CP_UTF8是个bug。真正的解决方法是使用入口点的宽字符版本,并使用 API 的宽字符版本。用户输入(尤其是文件名)不在您的控制范围内,处理它的唯一可行方法是始终使用 Unicode (UTF-16LE)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 2019-05-28
相关资源
最近更新 更多