char* 和 wchar_t*转换的问题

时间:2022-08-11 20:13:39
char * arg = "hello";
printf(" char * argList  : %p\n",arg);

wchar_t **pp1 = (wchar_t* *)(arg);
printf(" wchar_t ** pp1  : %p\n",pp1);


wchar_t *p1 = ( *pp1 );

wchar_t **pp1_2 = (wchar_t **)&p1;
printf(" wchar_t **pp1_2 : %p\n",pp1_2);


为什么最后一次输出和前面不同了呢?

18 个解决方案

#1


你的这些转换是毫无意义的

#2


char* 和 wchar_t*转换:在windows中有特定的函数实现char和wchar的转换的.

wchar转换成char:MultiByteToWideChar()..用法自己MSDN.

#3


&p1---是p1指针变量(wchar_t *)的地址,不是*pp1的值

#4


我这样就没问题了

#include "stdafx.h"
#include <stdio.h>


int main(int argc,char** argv)
{
char * arg = "hello";
printf(" char * argList : %p\n",arg);

wchar_t **pp1 = (wchar_t* *)(arg);
printf(" wchar_t ** pp1 : %p\n",pp1);

wchar_t *p1 = (wchar_t *)pp1;
printf(" wchar_t * p1 : %p\n",p1);

wchar_t **pp1_2 = (wchar_t **)p1;
printf(" wchar_t **pp1_2 : %p\n",pp1_2);

getchar();
return 0;
}

你的程序会前后不一致,在于这一步
wchar_t *p1 = ( *pp1 );
这里是把pp1的内容赋给p1了,而不是地址
要改成
wchar_t *p1 = (wchar_t *)pp1;

#5


楼上樱木, 正解!!!!!!!!!!!!

#6


这个与wchar_t没关系,就是指针的转换
你最初的程序与以下的一样:
main()
{
char * arg = "hello";
printf(" char * argList : %p\n",arg);

char **pp1 = (char* *)(arg);
printf(" wchar_t ** pp1 : %p\n",pp1);


char *p1 = ( *pp1 );

char **pp1_2 = (char**)&p1;
printf(" wchar_t **pp1_2 : %p\n",pp1_2);


}

#7


引用 1 楼 lhcwjy 的回复:
你的这些转换是毫无意义的


有意义,我需要在这里用到 http://topic.csdn.net/u/20100417/13/171b5b52-32c1-495c-9cf4-d932740e5661.html

#8


VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!

#9


还不明白吗?

wchar_t *p1 = ( *pp1 );
wchar_t **pp1_2 = (wchar_t **)&p1;//这里取的是指针变量p1的地址内容
printf(" wchar_t **pp1_2 : %p\n",pp1_2);

上面的代码跟下面的代码打印结果的没区别:

wchar_t *p1;//不赋值
wchar_t **pp1_2 = (wchar_t **)&p1;
printf(" wchar_t **pp1_2 : %p\n",pp1_2);//打印变量p1的地址

#10


对于你这个封装的问题,可以按以下几步处理:
1。对可变参数列数进行分析,分析出每个参数的类型。
2。构造新的参数列表,对wchar_t和wchar_t *的参数做转换.
3。由于参数数量是不定的,要把新的参数列表封装在一个结构的数组内。
因为没有用过你那个库,我搞了一个对printf的封装,用法完全一样。只是感觉参数的解析是最麻烦的。
所以我只做了简单的示例:
//取得参数对齐后的长度
#define INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define BUFSIZE 100 //参数缓冲区,要足够大
struct paramlist
{
char pl[BUFSIZE];
};


int myprintf(const wchar_t *format,...)
{
setlocale(LC_ALL,"");
paramlist param;
bool flag=false;
const char *srclist=(const char *)&format+INTSIZEOF(format);
const char *dstlist=param.pl;
size_t size=wcstombs(0,format,0);
char *formata=new char[size+1];
wcstombs(formata,format,size);
formata[size]=0;
//对原参数列表进行解析和遍历,构造新的参数列表,把wchar_t转换为char,把wchar_t * 转换为char *,
for (const wchar_t *p=format;*p!=0;p++)
{
if (*p=='%')
flag=true;
else
{
if (flag)
{
switch(*p)
{
case 's':
{
size=wcstombs(0,*(wchar_t **)srclist,0);
*(char **)dstlist=new char[size+1];
wcstombs(*(char **)dstlist,*(wchar_t **)srclist,size);
(*(char **)dstlist)[size]=0;

dstlist+=INTSIZEOF(wchar_t *);
srclist+=INTSIZEOF(wchar_t *);
break;
}
case 'd':
{
*(int *)dstlist=*(int *)srclist;
dstlist+=INTSIZEOF(int);
srclist+=INTSIZEOF(int);
break;
}

}
flag=false;
}
else
flag=false;
}

}
printf(formata,param);
//释放动态分配的内存
delete formata;

srclist=(const char *)&format+INTSIZEOF(format);
dstlist=param.pl;
for (const wchar_t *p=format;*p!=0;p++)
{
if (*p=='%')
flag=true;
else
{
if (flag)
{
switch(*p)
{
case 's':
{
delete *(char **)dstlist;
dstlist+=INTSIZEOF(wchar_t *);
break;
}
case 'd':
{
dstlist+=INTSIZEOF(int);
break;
}

}
flag=false;
}
else
flag=false;
}

}


return 0;
}

#11


int main()
{

myprintf(L"中a%d %s",1,L"aaa");

system("pause");  

只解析了printf中的 "d"和"s"两种参数

#12


前一段时间用了iconv,觉得还行,推荐之

#13


晕,看错了,以为是编码

请无视12楼

#14


额,又看了下,iconv是可以的

#15


当wchar_t字符转换为两个字节时是无法处理的。

#16


引用 8 楼 zhao4zhong1 的回复:
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!


我确实对汇编了解太少,

多谢提示

#17


大家稍等啊。马上结贴。

#18


引用 11 楼 lhcwjy 的回复:
C/C++ code
int main()
{

    myprintf(L"中a%d %s",1,L"aaa");
    
    system("pause");  


只解析了printf中的 "d"和"s"两种参数


感谢!

#1


你的这些转换是毫无意义的

#2


char* 和 wchar_t*转换:在windows中有特定的函数实现char和wchar的转换的.

wchar转换成char:MultiByteToWideChar()..用法自己MSDN.

#3


&p1---是p1指针变量(wchar_t *)的地址,不是*pp1的值

#4


我这样就没问题了

#include "stdafx.h"
#include <stdio.h>


int main(int argc,char** argv)
{
char * arg = "hello";
printf(" char * argList : %p\n",arg);

wchar_t **pp1 = (wchar_t* *)(arg);
printf(" wchar_t ** pp1 : %p\n",pp1);

wchar_t *p1 = (wchar_t *)pp1;
printf(" wchar_t * p1 : %p\n",p1);

wchar_t **pp1_2 = (wchar_t **)p1;
printf(" wchar_t **pp1_2 : %p\n",pp1_2);

getchar();
return 0;
}

你的程序会前后不一致,在于这一步
wchar_t *p1 = ( *pp1 );
这里是把pp1的内容赋给p1了,而不是地址
要改成
wchar_t *p1 = (wchar_t *)pp1;

#5


楼上樱木, 正解!!!!!!!!!!!!

#6


这个与wchar_t没关系,就是指针的转换
你最初的程序与以下的一样:
main()
{
char * arg = "hello";
printf(" char * argList : %p\n",arg);

char **pp1 = (char* *)(arg);
printf(" wchar_t ** pp1 : %p\n",pp1);


char *p1 = ( *pp1 );

char **pp1_2 = (char**)&p1;
printf(" wchar_t **pp1_2 : %p\n",pp1_2);


}

#7


引用 1 楼 lhcwjy 的回复:
你的这些转换是毫无意义的


有意义,我需要在这里用到 http://topic.csdn.net/u/20100417/13/171b5b52-32c1-495c-9cf4-d932740e5661.html

#8


VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!

#9


还不明白吗?

wchar_t *p1 = ( *pp1 );
wchar_t **pp1_2 = (wchar_t **)&p1;//这里取的是指针变量p1的地址内容
printf(" wchar_t **pp1_2 : %p\n",pp1_2);

上面的代码跟下面的代码打印结果的没区别:

wchar_t *p1;//不赋值
wchar_t **pp1_2 = (wchar_t **)&p1;
printf(" wchar_t **pp1_2 : %p\n",pp1_2);//打印变量p1的地址

#10


对于你这个封装的问题,可以按以下几步处理:
1。对可变参数列数进行分析,分析出每个参数的类型。
2。构造新的参数列表,对wchar_t和wchar_t *的参数做转换.
3。由于参数数量是不定的,要把新的参数列表封装在一个结构的数组内。
因为没有用过你那个库,我搞了一个对printf的封装,用法完全一样。只是感觉参数的解析是最麻烦的。
所以我只做了简单的示例:
//取得参数对齐后的长度
#define INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define BUFSIZE 100 //参数缓冲区,要足够大
struct paramlist
{
char pl[BUFSIZE];
};


int myprintf(const wchar_t *format,...)
{
setlocale(LC_ALL,"");
paramlist param;
bool flag=false;
const char *srclist=(const char *)&format+INTSIZEOF(format);
const char *dstlist=param.pl;
size_t size=wcstombs(0,format,0);
char *formata=new char[size+1];
wcstombs(formata,format,size);
formata[size]=0;
//对原参数列表进行解析和遍历,构造新的参数列表,把wchar_t转换为char,把wchar_t * 转换为char *,
for (const wchar_t *p=format;*p!=0;p++)
{
if (*p=='%')
flag=true;
else
{
if (flag)
{
switch(*p)
{
case 's':
{
size=wcstombs(0,*(wchar_t **)srclist,0);
*(char **)dstlist=new char[size+1];
wcstombs(*(char **)dstlist,*(wchar_t **)srclist,size);
(*(char **)dstlist)[size]=0;

dstlist+=INTSIZEOF(wchar_t *);
srclist+=INTSIZEOF(wchar_t *);
break;
}
case 'd':
{
*(int *)dstlist=*(int *)srclist;
dstlist+=INTSIZEOF(int);
srclist+=INTSIZEOF(int);
break;
}

}
flag=false;
}
else
flag=false;
}

}
printf(formata,param);
//释放动态分配的内存
delete formata;

srclist=(const char *)&format+INTSIZEOF(format);
dstlist=param.pl;
for (const wchar_t *p=format;*p!=0;p++)
{
if (*p=='%')
flag=true;
else
{
if (flag)
{
switch(*p)
{
case 's':
{
delete *(char **)dstlist;
dstlist+=INTSIZEOF(wchar_t *);
break;
}
case 'd':
{
dstlist+=INTSIZEOF(int);
break;
}

}
flag=false;
}
else
flag=false;
}

}


return 0;
}

#11


int main()
{

myprintf(L"中a%d %s",1,L"aaa");

system("pause");  

只解析了printf中的 "d"和"s"两种参数

#12


前一段时间用了iconv,觉得还行,推荐之

#13


晕,看错了,以为是编码

请无视12楼

#14


额,又看了下,iconv是可以的

#15


当wchar_t字符转换为两个字节时是无法处理的。

#16


引用 8 楼 zhao4zhong1 的回复:
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!


我确实对汇编了解太少,

多谢提示

#17


大家稍等啊。马上结贴。

#18


引用 11 楼 lhcwjy 的回复:
C/C++ code
int main()
{

    myprintf(L"中a%d %s",1,L"aaa");
    
    system("pause");  


只解析了printf中的 "d"和"s"两种参数


感谢!