printf之类的函数问题! [英] printf like function question!

查看:100
本文介绍了printf之类的函数问题!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请运行下面的代码.

Please run the code below.

<br />int main(int argc, char* argv[])<br />{<br />	int ii = 20;<br />	char tmp[32] = "loveing";<br />	printf("[%d]hello[%s]\n", tmp); //no integer fill the %d format<br /><br />	char szData[52] = {0};<br />	sprintf(szData, "[%d]saying [%s]\n",ii);//no string fill the %s format<br />	printf("%s", szData);<br />	return 0;<br />}



编译器在编译阶段不会抱怨,但是当您按F5进行调试时,会提示未处理异常".虽然不进行调试,但立即运行它,您只会得到使用的字符串或输出.

我们都在代码中使用了某种printf或CString :: Format,我们有时并不小心.那么如何处理此问题或检查现有项目中的错误呢?



The compiler don''t complain in the compile phase, but when you press F5 to debug, ''unhandle exception'' prompt. while not debug, run it at once, you just get wield strings or output.

We all use some sort of printf or CString::Format in the code, we are not careful sometimes. So how to handle this problem or check out the bugs in the exist project?

推荐答案

静态代码分析工具(例如Lint)和VS2010 Ultimate附带的静态代码分析工具,可能帮助您,但我会说经验是您最好的朋友.凭着经验,您知道应该避免使用哪种构造,以及哪些需要格外小心.在字符串内部浮动的格式说明符就是一回事.您所举的例子可能不是最骗人的.想象一下,如果格式字符串本身来自外部源(例如语言资源DLL),并且其他人可以翻译该源,那么会发生什么情况.在这种情况下,保护自己几乎是不可能的.

尽可能使用流,这是安全的替代方法.并且,如果您需要C样式的格式字符串,请确保由未经经验的程序员编写,以确保它们被代码审查覆盖.

错过了这一日期.为什么要撞到Yusuf?
Static code analysis tools like Lint and the the one that ships with VS2010 Ultimate, might help you there, but I would say experience is your best friend. With experience you know which constructs to avoid, and which needs extra care. Format specifiers floating around inside a string of characters is one such thing. The example you are giving is maybe not the most deceitful one. Imagine what can happen if the format string itself comes from an extern source, like a language resource DLL, which can be translated by someone else. In this case it''s almost impossible to protect yourself.

Use streams wherever possible, which is the safe alternative. And if you need C-style format strings, make sure they are covered in a code review, if written by an unexperienced programmer.

Missed the date on this one. Why did you bump it Yusuf?


如果您使用的是C ++,则没有理由使用printf或整个可怕的C语言家族.使用流.然后,您将获得类型安全性,并且不会尝试从堆栈中读取返回地址以将其解释为字符串.考虑按照以下方式重写:

If you''re using C++ there''s no reason to use printf or the whole god awful family of C relics. Use a stream. Then you get type safety and you won''t try reading return addresses off the stack to interpret as strings. Consider rewriting along the lines of:

int main()
{
    int d = 20;
    const std::string s( "Good Looking!" );

    std::cout << "[" << d << "] Hello " << s << std::endl;
}


您会发现代码一样快,甚至可能更快,并且编译器会告诉您,使代码混乱的可能性较小.

干杯,



PS:也错过了日期...与死者交谈通常不是我的事.


You''ll find the code''s as fast, probably faster and you''ve less chance of messing it up as the compiler will tell you.

Cheers,

Ash

PS: Missed the date as well... Talking to the dead isn''t normally my thing.


很抱歉,很长的帖子,但这是我的解决方法(有一个DT ...是我的库前缀.

Microsoft安全字符串库中的外观相似的函数,但是我能够使它们中的每个抛出异常.在常见情况下.这组代码必须在DLL中运行,该DLL记录了错误,因此它不能引发异常(尽管我认为在极少数情况下可以抛出异常.)

Sorry for the long post, but here''s my solution (there is a companion wide string set of functions as well.) The DT... is my library prefix.

There are similar looking functions in Microsoft safe string library, but I was able to cause every one of them to throw exceptions in common scenarios. This set of code had to run in a DLL which logged errors so it simple couldn''t throw exceptions (though I suppose it could in very fringe cases.)

<br />#include <span class="code-keyword"><stdarg.h></span><br /><br />inline<br />char* DTSafeStrCopyLen(LPSTR pDst, LPCSTR pSrc, int len)<br />{<br />	if (pDst)<br />	{<br />		if (pSrc && len > 0)<br />		{<br />			while (len && *pSrc)<br />			{<br />				*pDst++ = *pSrc++;<br />				len--;<br />			}<br />		}<br />		*pDst = 0;<br />	}<br />	return pDst;<br />}<br /><br />inline<br />int DTSafeStrCopyLen2(LPSTR pDst, LPCSTR pSrc, int len)<br />{<br />	return DTSafeStrCopyLen(pDst, pSrc, len) - pDst;<br />}<br /><br />#pragma warning(disable:4702) // unreachable code<br /><br />int DTSafeFormatStringV(LPSTR pBuffer, int bufferLen, LPCSTR pFormat, va_list args)<br />{<br />	if (!pBuffer || bufferLen <= 0)<br />		return -1;<br /><br />	int returnLen = 0;<br /><br />	if (pFormat && *pFormat)<br />	{<br />#if _MSC_VER >= 8<br />		__try<br />#else<br />		try<br />#endif<br />		{<br />			returnLen = _vsnprintf(pBuffer, bufferLen, pFormat, args);<br />			if (returnLen < 0)<br />			{<br />				pBuffer[bufferLen - 1] = 0;<br />				returnLen = bufferLen - 1;<br />			}<br />		}<br />#if _MSC_VER >= 8<br />		__except (EXCEPTION_EXECUTE_HANDLER)<br />#else<br />		catch (...)<br />#endif<br />		{<br />			returnLen = DTSafeStrCopyLen2(pBuffer, "!exception thrown during formatting: \"", bufferLen);<br />			returnLen += DTSafeStrCopyLen2(&pBuffer[returnLen], pFormat, bufferLen - returnLen); <br /><br />			if (returnLen < bufferLen - 1)<br />			{<br />				pBuffer[returnLen++] = ''"'';<br />				pBuffer[returnLen] = 0;<br />			}<br />		}<br />	}<br />	else<br />	{<br />		pBuffer[0] = 0;<br />	}<br /><br />	return returnLen;<br />}<br /><br />int DTSafeFormatString(LPSTR pBuffer, int bufferLen, LPCSTR pFormat, ...)<br />{<br />	if (!pBuffer || bufferLen <= 0)<br />		return -1;<br /><br />	int returnLen = 0;<br /><br />	if (pFormat && *pFormat)<br />	{<br />		va_list args;<br />		va_start (args, pFormat);<br />		returnLen = DTSafeFormatStringV(pBuffer, bufferLen, pFormat, args);<br />		va_end (args);<br />	}<br />	else<br />	{<br />		pBuffer[0] = 0;<br />	}<br /><br />	return returnLen;<br />}<br />






这篇关于printf之类的函数问题!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆