VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 488|回复: 2

自己写的这一小段代码为什么不能得到正常输出

[复制链接]
63_avatar_middle
最佳答案
0 
online_vip 发表于 2019-1-13 22:41:27 | 显示全部楼层 |阅读模式
3驿站币
看windows程序设计第五版的时候,第二章末尾有段代码,如下:
  1. #include<windows.h>
  2. #include<tchar.h>
  3. #include<stdio.h>

  4. int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, ...)
  5. {
  6.         TCHAR szBuffer[1024];
  7.         va_list pArgList;
  8.         va_start(pArgList, szFormat);
  9.         _vsntprintf(szBuffer,sizeof(szBuffer) / sizeof(TCHAR),
  10.                 szFormat, pArgList);
  11.         va_end(pArgList);
  12.         return MessageBox(NULL, szBuffer, szCaption, 0);



  13. }

  14. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  15.         PSTR szCmdLine, int iCmdShow)
  16. {

  17.         int cxScreen, cyScreen,z;
  18.         cxScreen = GetSystemMetrics(SM_CXSCREEN);
  19.         cyScreen = GetSystemMetrics(SM_CYSCREEN);
  20.         z = 521;
  21.         MessageBoxPrintf(TEXT("ScreenSize"),
  22.                 TEXT("The screen is %i pixels wide by %i pixels high and z is %d."),
  23.                 cxScreen, cyScreen,z);
  24.         return 0;
  25. }
复制代码


不太理解下面这一句:
  1. _vsntprintf(szBuffer,sizeof(szBuffer) / sizeof(TCHAR),
  2.                 szFormat, pArgList);
复制代码

就写了自己的代码,如下:
  1. #include<stdio.h>
  2. #include<stdarg.h>


  3. void Printf(char *szFormat, ...)
  4. {
  5.         char szBuffer[80];
  6.         va_list pArgList;
  7.         va_start(pArgList, szFormat);
  8.         sprintf_s(szBuffer,sizeof(szBuffer), szFormat, pArgList);
  9.         va_end(pArgList);
  10.          puts( szBuffer);



  11. }

  12. int main()
  13. {
  14.         char a = 'a';
  15.         char b[] = "i love cctry.";

  16.         Printf("int a is %c,b is %s.\n",a,b);

  17.         return 0;
  18. }
复制代码


可是运行后,并不能得到正确结果,大家来看看是咋回事啊

自己写的这一小段代码为什么不能得到正常输出





上一篇:新手 MFC 求助两个 ListControl 控件如何联动?
下一篇:UpdateData()true 和 false 的区别是啥
51_avatar_middle
最佳答案
82 
online_admins 发表于 2019-1-13 23:28:31 | 显示全部楼层
因为这里是使用参数的格式化列表 va_list 来进行初始化的,所以不能使用 sprintf_s 进行普通的字符串格式化。
你看他原来使用的函数是 _vsntprintf,是通用类型的,那么与他对应的窄字节版本就是:vsnprintf
即使你不想使用带n的,想使用安全的版本 _s 的,那么与之对应的版本也是 vsprintf_s,而不是 sprintf_s,所以楼主的字符串才不会被格式化正确的结果。明白了吗?

所以修改建议就是把 sprintf_s 改成 vsprintf_s 就可以了!
63_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2019-1-14 08:12:40 | 显示全部楼层
Syc 发表于 2019-1-13 23:28
因为这里是使用参数的格式化列表 va_list 来进行初始化的,所以不能使用 sprintf_s 进行普通的字符串格式化 ...

谢谢老大!!!!有些明白了。
老大看我理解的对不:
sprintf_s第四个及以后的参数应该是类似这样的,是要分别写出来的:
  1. char szBuffer[100];
  2. sprintf(szBuffer,"The sum of %i and %i is %i",5,3,5+3);
  3. puts(szBuffer);
复制代码

而vsprintf_s第四个参数可以用pArglist

也就是书里边下面这个列表,其中“可变数目的参数”和“参数数组的指针”的区别???

                    ASCII        宽字符       通用
可变数目的参数
标准版              sprintf      swprintf    _stprintf

最大长度版         _snprintf    _snwprintf   _sntprintf

Windows版           wsprintfA    wsprintfW    wsprintf

参数数组的指针
标准版              vsprintf     vswprintf_   vstprintf

最大长度版          _vsnprintf   _vsnwprintf _vsntprintf

Windows版           wvsprintfA   wvsprintfW  wvsprintf
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-9-25 05:35

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表