sprintf_s崩溃了

时间:2011-05-05 03:35:44

标签: c++ winapi

我在sprintf_s上偶尔执行以下代码时遇到了崩溃。这段代码工作了很多年没有任何问题。当我在strcat_s和sprintf_s中给出大小时,如下面的语句中所示,崩溃没有出现。这可能是什么原因?

strcat_s(sztmpCurrDate,的 100 下,sztmpCurrTime); sprintf_s(sztmpCurrDate,的 100 下, “%S:%0.3D”,sztmpCurrDate,curTime.wMilliseconds););

char sztmpCurrDate[100] = "";
char sztmpCurrTime[100] = "";
SYSTEMTIME curTime;
GetLocalTime(&curTime); 
GetLocalTime(&curTime); 
GetDateFormat(LOCALE_USER_DEFAULT,
                                DATE_SHORTDATE,
                                &curTime,
                                NULL,
                                sztmpCurrDate,
                                100);

GetTimeFormat(LOCALE_USER_DEFAULT,
                          TIME_FORCE24HOURFORMAT,
                          &curTime,
                          "HH':'mm':'ss",
                          sztmpCurrTime,
                          100);

strcat_s(sztmpCurrDate," ");
strcat_s(sztmpCurrDate,sztmpCurrTime);
sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);

4 个答案:

答案 0 :(得分:4)

来自documentation for sprintf_s

  

如果在重叠的字符串之间发生复制,则行为未定义。

您的代码:

sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);

从源位置复制到目标sztmpCurrDate。此外,您还没有指定sprintf_s所需的目标字符串的大小(我不知道您的代码是如何编译的那样)。尝试:

sprintf_s(sztmpCurrDate + strlen(sztmpCurrDate), 100-strlen(sztmpCurrDate),
          ":%0.3d",curTime.wMilliseconds);

更好的方法,因为你正在使用C ++,就是使用std::string然后你不必担心这种C字符串操作错误。

答案 1 :(得分:1)

语法错误!!!

sprintf_s的第二个参数是缓冲区的长度,在程序崩溃的情况下,你提供了指向C string(char *)的指针。这绝对是语法错误。

编译器可能发出警告,但遗憾的是让它通过了。这是因为sprintf_s接受三个参数+可变数量的参数。在你错的情况下你提供了三个参数,所以编译器满意,但他对待你的"格式字符串" as"参数数量"和sztmpCurrDate为"格式化字符串"。

如果您使用了具有固定数量参数的任何其他函数,并且您提供的参数少于需要,则这将是编译错误。

答案 2 :(得分:0)

代码工作正常,代码不正确。

sprintf(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);

重写为

sprintf(&sztmpCurrDate[strlen(sztmpCurrDate)],"%0.3d",curTime.wMilliseconds);

对于家庭工作告诉我们为什么.....

答案 3 :(得分:0)

您可能使用的版本不正确:

sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);

相反它应该是:

int slen = strlen(sztmpCurrDate) + 1;

sprintf_s(sztmpCurrDate, slen, "%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);

有关详细信息,请参阅此sprintf_s