sprintf输出一个额外的字符串

时间:2013-03-31 10:57:27

标签: c++

使用sprintf输出一个额外的字符串,例如"%x ...."

int main()
{   
    char *word_tmp = new char[0];
    char *word_all = new char[0];

    for(int i=0;i<5;i++)
    {
        sprintf(word_tmp, "\nNumber:%d, Good Good!", i);
        sprintf(word_all, "%s%s", word_all, word_tmp);   
    }

    std::cout<<word_all;
}

该程序工作正常,但输出一个我没有输出的字符串。

3 个答案:

答案 0 :(得分:3)

您的数组的长度为零,因此缓冲区word_tmp不足以容纳第一次调用sprintf()的结果,从而导致缓冲区溢出。因此,在这种情况下,第一次调用sprintf()的行为未定义。

除此之外,if copying takes place between objects that overlap as a result of a call to sprintf() or snprintf(), the results are undefined

最后,您的函数正在泄漏内存,因为您没有为分配了delete[]的数组调用new[]

你应该使用std::ostringstream以类型安全的方式完成你想要实现的目标(James Kanze用于查找我之前尝试为您的程序生成最小修补程序的问题):

#include <iostream>
#include <sstream>

int main()
{
    std::ostringstream ss;
    for (int i = 0; i < 5; i++)
    {
        ss << "Number: " << i << ", Good Good!" << std::endl;
    }

    std::cout << ss.str();
}

这是live example

答案 1 :(得分:0)

我真的很惊讶这段代码没有崩溃......你的sprintf目标字符串没有足够的空间来放置数据。而且我只是键入man sprintf并阅读:

C99  and  POSIX.1-2001 specify that the results are undefined if a call to sprintf(),
snprintf(), vsprintf(), or vsnprintf() would cause copying to take place between objects 
that overlap (e.g., if the target string array and one of the
supplied input arguments refer to the same buffer).

所以你的第二个sprintf在c99中是未定义的。

使用C ++ new运算符并使用sprintf追加字符串并将数字插入字符串也很奇怪,在C ++中,你有std :: string并蜇流以安全的方式执行此操作。

我认为您需要阅读一些书籍并了解c和c ++中的内容。

答案 2 :(得分:0)

首先,您永远不想使用sprintf。这几乎是不可能的 正确使用。在这种情况下,您将输出它的值 内存不存在,因此您有未定义的行为。 (你认为new char[0]会有多少记忆 分配?。在第二个sprintf中,您还要输入 不存在的内存 - 更多未定义的行为,以及 你输出和输入相同的内存(假设 有任何记忆),这也是未定义的行为。

忘了sprintf和数组新:

std::string results;
for ( int i = 0; i != 5; ++ i ) {
    std::ostringstream s;
    s << "Number: " << i << " Good Good!\n";
    results += s.str();
}
std::cout << results;

(我认为这就是你要做的。)

最后一点:虽然它几乎从来不是一个真正的问题,但标准确实要求输出到文本流的最后一个字符(如std::cout)为'\n'