关于CString类中format方法的奇怪问题.

fish_kun 2008-01-14 10:29:46
今天帮同学调试代码,发现了一个很奇怪的问题.

他在资源中定义了一个字符串 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让我有些整不明白,各位能帮我解释一下吗,
先谢过了,我是知其然,不知其所以然,知道修改,但不知道为什么,呵呵.
...全文
144 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
cospolo 2008-01-17
  • 打赏
  • 举报
回复
CString::Format这个函数用自己来作参数是很危险的,根据语义,它会对"%d"这类的做替换。

sRes.Format(sRes, count);语义变为将内容为“Users: %d”的字符串中的%d用对应整数的字符串替换,而此字符串本身又作为格式参数。会有%d替换的问题出现,当count>=100后,%d会被“100”替换,而此时替换的字符串是“100”,是三个字符组成,而此前的“%d”是两个字符组成,而这种用法本身迭代“%d“替换两次,所以当将"100"或类似超过两个字符组成的字符串拿来替换“%d”时,肯定会有越界访问发生。
fish_kun 2008-01-15
  • 打赏
  • 举报
回复
是啊,他的代码不该那样写,可是,为什么在count<100的时候没有出问题呢?
iyranly 2008-01-15
  • 打赏
  • 举报
回复
严重同意一下7楼的意见!

是的,不能只用一个变量,这中间需要一个变量来进行格式化的中转

CString strFmt="这样就对了";
CString str;
str.Format("%s%d",strFmt,100);

这个代码看着就舒服多了!
lsyxp17 2008-01-15
  • 打赏
  • 举报
回复
楼上说的好有道理哦
junheng 2008-01-15
  • 打赏
  • 举报
回复
原因不在于被格式化的数据,也不在于LoadString有什么问题。而是CString::Format函数的问题。
一般情况下,Format函数不允许将其本身格式化。比如:
CString str="这样是不对的";
str.Format("%s%d",str,100);
这样就会导致错误。
所以,如果要对一个字符串格式化,就应该写成这种格式:
CString strFmt="这样就对了";
CString str;
str.Format("%s%d",strFmt,100);
fish_kun 2008-01-14
  • 打赏
  • 举报
回复
To hdt:
再说详细一些嘛,我没有完全明白.
真相重于对错 2008-01-14
  • 打赏
  • 举报
回复
100会替换为把%d 3个字符,所以出错
改为
CString sRes,sFormat;
sFormat.LoadString(IDS_USER_COUNT);
int count;
count = 1000;
sRes.Format(sFormat, count);
fish_kun 2008-01-14
  • 打赏
  • 举报
回复
关键是为什么count>=100才导致错误呢?
随便说一下,这个程序用的是Unicode编码。
caofusheng 2008-01-14
  • 打赏
  • 举报
回复
看看这个吧。也许有用。
http://wflyfox.bokee.com/670276.html
shelliu 2008-01-14
  • 打赏
  • 举报
回复
这种用法还是第一次看到,有趣!
zyyoung 2008-01-14
  • 打赏
  • 举报
回复
LoadString的函数原型,看一下

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧