c语言windows程序设计电子书,C语言Windows程序设计-在Windows中使用printf

在Windows中使用printf

==============

一、可变参函数

在Windows程序设计中, 由于Windows不存在标准输入输出的概念, 这就意味这以前我们学习的printf函数将不再适用, 我们知道, C语言标准输入输出函数printf一个常用的功能就是输出格式化后的文字, 例如:

int iAge = 18;

printf("Hello, I am %d years old.\n", iAge );

是的, printf函数的使用确实十分方便, 今天上午的学习我们要做的就是完成一个Windows版的printf。

关于sprintf:

看一个C语言的函数, sprintf函数, 这个函数在stdio.h头文件中有声明, sprintf函数的主要功能是把格式化的数据写入某个字符串中, 函数的原型如下:

int sprintf( char *buffer, const char *format, [ argument] … );

sprintf的第一个参数为字符缓冲区, 后面的参数就像printf一样, 是一个格式化字符串, 函数的返回值为缓冲区buffer内的有效字符串长度, 我们尝试使用一下:

30154899_1.gif#include

intmain()

{char szBuffer[50] ;   //定义缓冲区大小为50字节

sprintf( szBuffer, "today: %d-%d-%d", 2012, 10, 8 ) ;   //将今天的日期格式化输出到缓冲区

puts( szBuffer ) ;   //输出缓冲区szBuffer中的字符

return 0;

}

30154899_1.gif

先在我们已经能看到Windows版的printf的影子了, 在Windows版的printf中, 我们可以使用MessageBox函数来替代C语言的标准输入输出函数puts, 但是在这之前我们还有一个重要的问题要解决。

sprintf的安全版

当我们使用sprintf时, 我们需要首先定义一个缓冲区, 这个缓冲区我们必须定义的足够大以至于能容纳我们格式化输出的字符串, 如果超过了这个长度, 程序将会出错, 这样是不安全的, 这里, 使用_snprintf()函数来解决这个问题, _snprintf的原型为:

int _snprintf(char *szBuffer, size_t size, const char *format, ...);

_snprintf相对于sprintf函数多出了个参数, size_t size, 这个参数的功能是:

当格式化后的字符串长度  size,则仅复制( size - 1 )个字符到缓冲区szBuffer内, 并在其后添加一个字符串结束符('\0') 。

我们自己的可变参函数

sprintf有个变形函数, 叫vsprintf, 首先看下这个函数的原型:

int vsprintf(char *szBuffer, const char *format, va_list param);

vsprintf的前两个参数与sprintf相同, 第三个参数为一个va_list宏, va_list宏就是解决C语言变参问题的。

va_list宏的用法:

我们将用到valist的以下几个成员:

va_list、va_start、va_end;

在些宏在STDARG.H头文件中有定义,打开STDARG.H可以看到,其中有句:

typedef char * va_list;

从这句我们可以看出,va_list其实就是char*型类型, 一个字符型指针;

再来看看va_start宏:

va_start(va_list ap, char*format);

format为函数的参数, 可以用来指明参数的类型

可以看出, ap为va_list类型, 也就是可变参数列表; 通过va_start后, 就能使得变参列表与format中的类型一一对应起来;

va_end的作用是销毁释放一个va_list型的参数列表, 例如:

va_list ap

va_end( ap );

下面我们就可以实现我们自己的变参了,代码如下:

30154899_1.gif#include #include

int mySprintf( char *szBuffer, const char *szFormat, ... )

{int iLength ;          //存储字符串的长度信息

va_list pArgs ;     //声明一个va_list型变量

va_start( pArgs, szFormat ) ;//让pArgs指向变参

iLength = vsprintf( szBuffer, szFormat, pArgs ) ;  //输出到缓冲区szBuffer中

va_end(pArgs);      //释放pArgs

return iLength ;    //返回字符串长度

}intmain()

{inti;char szBuffer[128] ;

i= mySprintf( szBuffer, "today: %d-%d-%d", 2012, 10, 8) ;

puts( szBuffer ) ;return 0;

}

30154899_1.gif

运行后的结果和sprintf是相同的, 说明我们已经实现了自己的可变参函数。

二、实现Windows版的printf

在上面的介绍中, 我们所使用的字符串处理函数都是针对于char型的, 下面我们将这些转换为wchar_t型来实现Windwos的格式化消息框。

vsprintf和sprintf一样, 也有其相对应的安全版(最大长度版), 为_vsnprintf, 为了程序的安全性, 这里我们使用vsprintf的安全版, _vsnprintf。

myMessageBox的实现,代码如下:

30154899_1.gif#include #include

int CDECL myMessageBox( TCHAR * szCaption, size_t iStyle, TCHAR *szFormat, ... )

{//myMessageBox函数参数: 标题, 样式, 格式化输出内容

//CDECL为调用规则, 在WINDEF.H定义为: #define CDECL _cdeclTCHAR szBuffer [1024] ;

va_list pArgs ;

va_start (pArgs, szFormat) ;

_vsnprintf( szBuffer,sizeof(szBuffer) / sizeof(TCHAR), szFormat, pArgs ) ;//sizeof(szBuffer) / sizeof (TCHAR)得到最大能容下的字符个数va_end (pArgs) ;returnMessageBox(NULL, szBuffer, szCaption, iStyle) ;

}intWINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine,intiCmdShow)

{intcxScreen, cyScreen ;

cxScreen= GetSystemMetrics (SM_CXSCREEN) ; //获取显示器x方向像素cyScreen= GetSystemMetrics (SM_CYSCREEN) ; //获取显示器y方向像素myMessageBox( TEXT ("显示器分辨率"), MB_OKCANCEL, TEXT ("显示器当前分辨率为:%dx%d。"), TEXT(cxScreen), TEXT(cyScreen) ) ;return 0;

}

30154899_1.gif

30154899_2.png

--------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值