- 积分
- 106
- 实力分
- 点
- 金钱数
- 两
- 技术分
- 分
- 贡献分
- 分
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
2月8日 总结
提出这个函数时是由于wsprintf函数的不熟悉,也想为修改汉化程序提供了方便,通过阿冰和夜神的回帖,学到不少东西。
了解了wsprintf的使用方法,虽然在输出中文上不直观,但也不复杂,而gbprintf在调用上方便,但问题不少,
权衡利弊,决定放弃gbprintf啦,这贴子也算是一个学习笔记吧^_^
2月6日
先来一段新春感词,哈哈~
随着ANSI(GB)的ElfPack的到来,越来越多的Elf程序用ASNI(GB)编码来开发,
大家的开发热情也越来越高涨,各位机油也将有越来越多的中文Elf程序使用^_^。
当然这要感谢很多走前面的先锋们,没有他们的辛勤工作,我下面要讨论的东西也无从谈起了。
在这里对各位前辈表示敬意,当然也有各位机油冒着死机的危险勇敢测试的功劳,呵呵。
春节快到啦,祝我们这个大家庭的每个人新春快乐,万事如意!下面进入正题:
今天本来想把西机助手用GB编码改写,没想最后遇到一个问题:wsprintf函数最GB编码支持不是很好。
这个阿冰谈到过:
原帖由 binghelingxi 于 2008-1-29 22:55 发表
问题出现。。。
wsprintf函数用起来还是有点问题。。。
如果这样使用:
wsprintf(ws, "如果");
这样就会是乱码。
而如果用:
wsprintf(ws,"%t" "如果")
这样就正常。
wsprintf(ws1, "你好!"));
wsprintf(ws2, "%t","你好!");
查看ws1->wsbody[0], ws2->wsbody[0]分别为6和3
ws1->wsbody里面直接为ANSI码。。。
直接输入中文需要加格式"%t"(我到现在都查不到"%t"是什么含义),否则它把字符串ASCII码处理(即单字节),显示出来就是乱码了。
最大的问题是它不支持下面方法:
int num=10;
wsprintf(ws,"数值=%d",num); //这样无法正常显示中文的
这个很常用,但是却不支持,够郁闷。。。不可能多定义几个WSHDR变量,把格式串分开放,然后把它接起来吧?
后来想着自己写一个gbprintf函数吧,能完完全全支持GB编码。。。查了不少资料,测试时死机n次,终于成功了o(∩_∩)o...哈哈
主要参考了c语言printf的源代码和gb2ws函数的源代码。下面是函数代码,供大家一起讨论和完善:
#include "stdarg.h"
#ifdef NEWSGOLD
#define CODEMAP_ADDR 0xA1568200 //-0xA157A24F
#else
#define CODEMAP_ADDR 0xA0FA0200
#endif
//保存中文GB编码字符到WSHDR
char *getgbch(WSHDR *ws,char *ch)
{
unsigned short *codemap=(unsigned short *)CODEMAP_ADDR;
unsigned char uc,uc2;
uc=*ch++;
if(uc <= 128)
wsAppendChar(ws,uc);
else
{
uc2=*ch++;
if(uc2 < 128)
wsAppendChar(ws, uc2);
else
wsAppendChar(ws, codemap[(uc-129)*127+(uc2-128)]);
}
return ch;
}
//支持中文GB编码的gbprintf函数
int gbprintf(WSHDR *ws,const char *format,...)
{
ws->wsbody[0] = 0;//清零
char* chptr;
char str[256];//保存输出内容
char type[16];//保存输出格式
int typepos=0;
char *fmtptr=(char *)format;
va_list ap;//不定参数变量
va_start(ap,fmtptr);//不定参数开始
while (*fmtptr!='\0') {
if (*fmtptr == '%')//如果为百分号
{
type[typepos++]=*fmtptr++;//保存%,取下一个
while(typepos!=0&&*fmtptr!='\0')
{
switch(*fmtptr)
{
case 's'://字符串
type[typepos++]=*fmtptr++;
type[typepos]='\0';
sprintf(str,type,va_arg(ap,char*));
chptr=str;
while (*chptr!='\0')
{
chptr=getgbch(ws,chptr);
}
typepos=0;
break;
case 'c'://字符
type[typepos++]=*fmtptr++;
type[typepos]='\0';
sprintf(str,type,va_arg(ap,char*));
chptr=str;
while (*chptr!='\0')
{
wsAppendChar(ws,*chptr++);
}
//chptr = va_arg(ap,char*);
//getgbch(ws,chptr);
typepos=0;
break;
case 'i':
case 'd'://十进制整数
type[typepos++]=*fmtptr++;
type[typepos]='\0';
sprintf(str,type,va_arg(ap,int));
chptr=str;
while (*chptr!='\0')
{
wsAppendChar(ws,*chptr++);
}
typepos=0;
break;
case 'u'://无符号整数
case 'x'://小写十六进制整数
case 'X'://大写十六进制整数
case 'o'://八进制整数
type[typepos++]=*fmtptr++;
type[typepos]='\0';
sprintf(str,type,va_arg(ap,unsigned int));
chptr=str;
while (*chptr!='\0')
{
wsAppendChar(ws,*chptr++);
}
typepos=0;
break;
case 'f'://浮点数
type[typepos++]=*fmtptr++;
type[typepos]='\0';
sprintf(str,type,va_arg(ap,double));
chptr=str;
while (*chptr!='\0')
{
wsAppendChar(ws,*chptr++);
}
typepos=0;
break;
//支持的格式控制
case '.':
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
type[typepos++]=*fmtptr++;
break;
default://不满足直接输出,容错
fmtptr=getgbch(ws,fmtptr);
typepos=0;
}//switch
}//while
}//if %
else
{
fmtptr=getgbch(ws,fmtptr);
}
}
va_end (ap);//参数结束
return ws->wsbody[0];
}
说明:
使用方法和wsprintf一样,参数一样:__swi __arm int wsprintf (WSHDR *,const char*format,...);
接下来还希望实现一个像gbprintf(WSHDR *,char *str)的函数,估计不难,实现之后就不用这样了:wsprintf(ws2, "%t","你好!")。
目前支持的格式串:[0-9] '.' '-' %i %d %u %s %c %f %x %X %o
还不支持:'#' '*' 等等(有好想法可以自己编写控制格式^_^)
欢迎大家一起讨论,测试,完善它,弄成个标准,将大大方便GB编码程序的开发。之后可以最为API函数加到sieapi.h里面去。
现在已经是大年三十啦,过年回比较忙了,过年前完成一项工作,挺开心,好啦,睡觉啦,大家过年过得开心!!
[ 本帖最后由 DaiKangaroo 于 2008-2-8 23:17 编辑 ] |
|