今天帮同学调试代码,发现了一个很奇怪的问题.他在资源中定义了一个字符串 IDS_USER_COUNT "Users: %d"在其函数中,他这样使用:int count = 0;
......
//count被赋值
......CString sRes;
sRes.LoadString(IDS_USER_COUNT);
sRes.Format(sRes, count); //当count >= 100时,此处会导至程序crash.如何将代码改为
sRes.Format(IDS_USER_COUNT, count)或者sRes.Format(_T("Users: %d"), count),
可以正常运行.这里,
sRes.LoadString(IDS_USER_COUNT);
sRes.Format(sRes, count); //当count >= 100时,此处会导至程序crash.
这种写法肯定不好,但它在count>=100让我有些整不明白,各位能帮我解释一下吗,
先谢过了,我是知其然,不知其所以然,知道修改,但不知道为什么,呵呵.
......
//count被赋值
......CString sRes;
sRes.LoadString(IDS_USER_COUNT);
sRes.Format(sRes, count); //当count >= 100时,此处会导至程序crash.如何将代码改为
sRes.Format(IDS_USER_COUNT, count)或者sRes.Format(_T("Users: %d"), count),
可以正常运行.这里,
sRes.LoadString(IDS_USER_COUNT);
sRes.Format(sRes, count); //当count >= 100时,此处会导至程序crash.
这种写法肯定不好,但它在count>=100让我有些整不明白,各位能帮我解释一下吗,
先谢过了,我是知其然,不知其所以然,知道修改,但不知道为什么,呵呵.
解决方案 »
- CListCtrl::Arrange,SetItemPosition.的问题
- vc++6.0的安装问题:安装正常通过,一编译程序,就死了,只能结束任务来关掉
- 如何将word的类型库引入到VC中,我使用的是WTL开发.
- 请教:关于测试对象是否存在的问题?
- 请教#define IDC_EDIT1 WM_USER+1000 的问题!
- 关于VC Timer的问题
- 帮忙编个简单的小程序
- 很急又找不到答案又很初级的问题:怎么把我写的ActiveX里的事件可以在asp里调用
- 有谁看过《Visual C++数字图象处理》(人民邮电)一书,怎么样?
- 读取自定义HID设备,在以读方式打开设备CreateFile时GENERIC_READ一直返回5
- 如何获取某路径下的长中文文件名(windows系统)
- 无法参看CString类型值
http://wflyfox.bokee.com/670276.html
随便说一下,这个程序用的是Unicode编码。
改为
CString sRes,sFormat;
sFormat.LoadString(IDS_USER_COUNT);
int count;
count = 1000;
sRes.Format(sFormat, count);
再说详细一些嘛,我没有完全明白.
一般情况下,Format函数不允许将其本身格式化。比如:
CString str="这样是不对的";
str.Format("%s%d",str,100);
这样就会导致错误。
所以,如果要对一个字符串格式化,就应该写成这种格式:
CString strFmt="这样就对了";
CString str;
str.Format("%s%d",strFmt,100);
CString str;
str.Format("%s%d",strFmt,100); 这个代码看着就舒服多了!
sRes.Format(sRes, count);语义变为将内容为“Users: %d”的字符串中的%d用对应整数的字符串替换,而此字符串本身又作为格式参数。会有%d替换的问题出现,当count>=100后,%d会被“100”替换,而此时替换的字符串是“100”,是三个字符组成,而此前的“%d”是两个字符组成,而这种用法本身迭代“%d“替换两次,所以当将"100"或类似超过两个字符组成的字符串拿来替换“%d”时,肯定会有越界访问发生。