如何将LPWSTR转换为'const char*'

9

使用C++/CLI从C#获取结构体后,在C++中进行操作:

public value struct SampleObject
{   
    LPWSTR a;    
};

我想要打印它的实例:

printf(sampleObject->a);

但我收到了这个错误:

Error 1 error C2664: 'printf' : 无法将参数 1 从 'LPWSTR' 转换为 'const char *'

我该如何从 LPWSTR 转换为 char*

提前致谢。


1
你不能只这样做吗:printf((const char*)sampleObject->a); - Cyclonecode
@KristerAndersson 太棒了!为什么不自己回答呢,那我就把它标记为答案了!:D - olidev
5
不太可能奏效……这样做不会转换数据类型,只是告诉编译器不要担心它是错误的数据类型。 - jcoder
1
@JohnB 你说得对。它不起作用。我得到了一个转换异常。有什么想法吗? - olidev
在C++/CLI中,您可以直接使用marshal_asSystem::String^转换为char*,无需经过LPWSTR。 - Ben Voigt
6个回答

27

使用位于<stdlib.h>中的wcstombs()函数。以下是如何使用它:

LPWSTR wideStr = L"Some message";
char buffer[500];

// First arg is the pointer to destination char, second arg is
// the pointer to source wchar_t, last arg is the size of char buffer
wcstombs(buffer, wideStr, 500);

printf("%s", buffer);

希望对某人有所帮助!这个函数让我避免了很多沮丧。


谢谢,这节省了我将 LPWSTR 转换为可由 _cprintf() 显示的时间。 - V-SHY
即使是类型为 LPTSTR 的变量,也可以使用相同的方法存储在缓冲区中。 - V-SHY
这并不保证编码为UTF-8。请改用WideCharToMultiByte,并显式设置编码为UTF-8。请参考@79E09796的回答。 - andrewrk
@andrewrk 这是一个更复杂的函数,如果我们确定WSTR实际上只包含ASCII-7数据,则有这样的情况。 - peterh

5
只需使用printf("%ls", sampleObject->a)。在%ls中使用l表示您可以传递,例如L"Wide String"
(不,我不知道为什么L和w前缀总是混合使用)

4
int length = WideCharToMultiByte(cp, 0, sampleObject->a, -1, 0, 0, NULL, NULL);
char* output = new char[length];
WideCharToMultiByte(cp, 0, sampleObject->a, -1, output , length, NULL, NULL);
printf(output);
delete[] output;

1
使用WideCharToMultiByte()方法进行多字节字符转换。
以下是从LPWSTR到char*或从宽字符到字符的转换示例。
/*LPWSTR to char* example.c */
#include <stdio.h>
#include <windows.h>

void LPWSTR_2_CHAR(LPWSTR,LPSTR,size_t);

int main(void)
{   
    wchar_t w_char_str[] = {L"This is wide character string test!"};
    size_t w_len = wcslen(w_char_str);
    char char_str[w_len + 1];
    memset(char_str,'\0',w_len * sizeof(char));
    LPWSTR_2_CHAR(w_char_str,char_str,w_len);

    puts(char_str);
    return 0;
}

void LPWSTR_2_CHAR(LPWSTR in_char,LPSTR out_char,size_t str_len)
{   
    WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,in_char,-1,out_char,str_len,NULL,NULL);
}

1

这里有一个简单的解决方案。请查看 wsprintf

LPWSTR wideStr = "some text";
char* resultStr = new char [wcslen(wideStr) + 1];
wsprintfA ( resultStr, "%S", wideStr);

"

“%S”将隐式地将UNICODE转换为ANSI。

"

wsprintf()的文档页面现在有一个注释,警告不要使用它。 - Shane Bishop

-1

不要转换。

使用wprintf代替printf

请查看示例,了解如何使用它。

或者,您可以使用std::wcout,如下所示:

wchar_t *wstr1= L"string";
LPWSTR   wstr2= L"string"; //same as above
std::wcout << wstr1 << L", " << wstr2;

同样地,使用专为宽字符设计的函数,并忘记将 wchar_t 转换为 char 的想法,因为这可能会导致数据丢失。

在这里查看处理宽字符的函数:


5
不,我需要将它转换以执行其他任务。我之所以问这个问题是因为我需要先进行调试,以查看从C#传递到C++的对象是否有效。 - olidev
你有使用它的示例吗?这并不像 wsprintf(string) 那样容易。 - olidev
1
不好的建议。有些情况下确实需要进行转换。 - Predrag Manojlovic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接