C - sprintf()如何工作?

时间:2016-07-04 21:58:01

标签: c

我刚接触C编码并编写了一个程序,需要创建从0开始递增的自定义文件名。要创建文件名,我使用sprintf()来连接计数器和文件扩展名,如下所示: / p>

sprintf(filename, "0%02d.txt", count);

然而,每次

struct A
{
  uint32_t arr[size];
};

运行,count重置为0.

我的问题是,sprintf()对count做了什么?为什么计数在传递给sprintf()之后会发生变化?

非常感谢任何帮助。

编辑:对不起,我对问题中的代码一直不太清楚 - 我正在为在线课程上的练习编写程序,计数最多可达50个.I&I #39;我现在改变了我的代码来反映这一点。另外,感谢告诉我%04d,我使用了一个复杂的if语句来确定要添加到我的文件名中的多少个零以使其成为3位数。

2 个答案:

答案 0 :(得分:1)

尽管有问题的标题,但这与sprintf()无关,count可能会按预期运行,但所有内容都与static int count = 0; 无关。

如果count是一个全局变量(即在任何函数之外),那么它应该在函数调用之间保持其值。所以情况可能并非如此。

如果它是一个局部变量(在函数内声明),那么它可以有任何值,因为它们在函数结束时会丢失它们的值,并且在函数再次运行时不会被初始化。它可以总是0,但在不同的情况下,它也可以是其他东西。换句话说,该值或多或少未确定。

要让局部变量在函数调用之间保持其值,请将其设置为静态。

000.txt

但请注意,当您再次停止并运行程序时,它将再次从0开始。这意味着您可能会覆盖001.txt,然后覆盖"00%04d.txt"等等。

如果您真的想避免重复的文件名,则必须更复杂,并查看哪些文件已经存在,确定最高编号,并将其增加一。因此,您不使用变量,检查已存在的文件。这是更多的工作,但唯一可靠的方法是避免用这样的编号文件名覆盖现有文件。

FWIW,我会使用类似000000.txt之类的格式字符串,因此您可以获得文件000001.txt000.txt等,这些文件在字母顺序排序的文件列表中看起来比{{1}更好}},001.txt0010.txt0011.txt002.txt等。它们也更容易解析其数量。

正如风向标注意到的那样,一定要让你的缓冲区更大,例如

char filename[20];

太小的缓冲区是个问题。一个太大的东西不是,除非它是巨大的,并且堆栈上的垃圾。这个风险非常小,只有20个字符。

答案 1 :(得分:1)

我认为很可能是sprintf。 “0%02d.txt”是7个字符。字符串末尾的null将进入下一个位置,这可能是堆栈上的计数。在一个小端机器(x86)上,这可能意味着计数的底部字节在每个sprintf()中都被清零。

正如其他人所说。使文件名缓冲区更大。