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.
wchar转换成char:MultiByteToWideChar()..用法自己MSDN.
#3
&p1---是p1指针变量(wchar_t *)的地址,不是*pp1的值
#4
我这样就没问题了
你的程序会前后不一致,在于这一步
wchar_t *p1 = ( *pp1 );
这里是把pp1的内容赋给p1了,而不是地址
要改成
wchar_t *p1 = (wchar_t *)pp1;
#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);
}
你最初的程序与以下的一样:
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
有意义,我需要在这里用到 http://topic.csdn.net/u/20100417/13/171b5b52-32c1-495c-9cf4-d932740e5661.html
#8
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习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的封装,用法完全一样。只是感觉参数的解析是最麻烦的。
所以我只做了简单的示例:
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楼
请无视12楼
#14
额,又看了下,iconv是可以的
#15
当wchar_t字符转换为两个字节时是无法处理的。
#16
我确实对汇编了解太少,
多谢提示
#17
大家稍等啊。马上结贴。
#18
感谢!
#1
你的这些转换是毫无意义的
#2
char* 和 wchar_t*转换:在windows中有特定的函数实现char和wchar的转换的.
wchar转换成char:MultiByteToWideChar()..用法自己MSDN.
wchar转换成char:MultiByteToWideChar()..用法自己MSDN.
#3
&p1---是p1指针变量(wchar_t *)的地址,不是*pp1的值
#4
我这样就没问题了
你的程序会前后不一致,在于这一步
wchar_t *p1 = ( *pp1 );
这里是把pp1的内容赋给p1了,而不是地址
要改成
wchar_t *p1 = (wchar_t *)pp1;
#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);
}
你最初的程序与以下的一样:
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
有意义,我需要在这里用到 http://topic.csdn.net/u/20100417/13/171b5b52-32c1-495c-9cf4-d932740e5661.html
#8
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习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的封装,用法完全一样。只是感觉参数的解析是最麻烦的。
所以我只做了简单的示例:
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楼
请无视12楼
#14
额,又看了下,iconv是可以的
#15
当wchar_t字符转换为两个字节时是无法处理的。
#16
我确实对汇编了解太少,
多谢提示
#17
大家稍等啊。马上结贴。
#18
感谢!