2014-05-24 57 views
-2

我刚刚发现有关sprintf()(C++库函数)奇怪的事情。奇怪的行为或可能是错误sprintf()在c + +

看看这两种解决方案

Time limit Exceeded solution

Accepted Solution

他们之间的唯一区别是,我用

sprintf(a,"%d%c",n,'\0'); 
在TLE解决方案


交流我将sprintf()替换为

sprintf(a,"%d",n); 

你也可以观察到,一杆进洞的解决方案只有0.01秒和2.8MB内存
但TLE解决方案花了大约11.8MB check here

还有一个件事程序,给TLE运行在0中IDEONE了与极端的输入数据 所以它是一个错误CODECHEF本身

有人请解释我是这是一个错误或一些相当未知的操作在这里发生。

在此先感谢。

+1

这两个代码片段都没有包含'sscanf'。第一个'sscanf'显然是错误的(尝试读入一个字符常量?),第二个是有问题的('n'是一个指针?) – hobbs

+0

对不起,这个问题是关于'sprintf()'而不是'sscanf() '。 和n是一个整数变量,它始终小于100 – hkbharath

回答

0

首先,代码的差异是而不是sscanf,但与sprintf。代码的差异说明:

--- ac.c  2014-05-24 14:31:18.074977661 -0500 
+++ tle.c  2014-05-24 14:30:52.270650109 -0500 
@@ -4,7 +4,7 @@ 

string mul(string m, int n){ 
char a[4]; 
-sprintf(a,"%d",n); 
+sprintf(a,"%d%c",n,'\0'); 
int l1 = strlen(a); 
//printf("len : %d\n",l1); 
int l2 = m.length(); 

其次,通过明确地包装在一起%c'\0'字符串,你正在减少,可以通过1存储在整数的大小,您需要检查返回sprintf的。 man printf:

成功返回后,这些函数返回打印的字符数(不包括用于结束输出到字符串的尾部'\ 0')。

在您的情况下,您很可能会写入超出a[4]字符串的末尾,并且遇到未定义的结果。有a[4]您只有999\0的空间。当您明确添加%c + '\0'时,您将其减少到99\0\0。如果您的编号超过99,那么sprintf将写入超出字符串的末尾,因为您明确打包了额外的'\ 0'。在原始情况下,sprintf(a,"%d",n); 999可以存储在没有问题的情况下依靠sprintf将'\ 0'附加为[3]。

测试与n = 9999,sprintf的仍数存放在,但将返回5超过可用a[4]的空间,这意味着你的代码的行为是一个骰子滚在这一点上。

+0

好吧,我同意你的想法,但为什么我得到TLE它应该是错误的答案。或者这种不寻常的行为是由在字符串中添加额外的空字符引起的? – hkbharath

+0

未定义的行为意味着您的代码可以执行任何操作,正确地将整数输出到段错误(这只是未定义的)。我不知道'n'的值是什么,但在你的情况下,我怀疑他们是在100范围内。这意味着在sprintf返回超过4之后的任何时候,任何事情都可能在你的代码中发生(比如读取过程超出边界的末尾,并吸取额外的11.8 M你没有想到的东西(它是只是未定义)确保你不覆盖'a [4]'的结尾是防止意外的好开始。 –