每次调用printf()都会创建一个新的内部缓冲区,还是所有后续调用都使用与第一个相同的缓冲区?

时间:2018-02-11 21:53:17

标签: c printf c-strings

当我使用printf()处理一个小程序时,我注意到以下\t调用中使用的每个printf()字符都是从前一个{{1调用。

以下图片和代码示例将阐明我的意思。

预期产出的例子

screenshot of tabular output

printf()

为了在上面的图像中获得所需的输出,我期望必须这样做:

printf("\t%d", i); // Prints multiples of 1
printf("\t%d", i * 2); // Prints multiple of 2
printf("\t%d", i * 3); // ... multiple of 3
printf("\t%d", i * 4); // ... multiple of 4
printf("\t%d", i * 5); // ... multiple of 5
printf("\n"); // Starts new line after each number printed.

但是这不起作用,每次跟随printf()调用从前一个字符串的末尾继续,这是有道理的,因为我们不使用新行。

最终,我认为单个printf调用会做同样的事情,虽然可读性稍差,但开销可能较少。

printf("\t%d", i);
printf("\t\t%d", i * 2);
printf("\t\t\t%d", i * 3);
printf("\t\t\t\t%d", i * 4);
printf("\t\t\t\t\t%d", i * 5);

这让我对printf()如何工作感到好奇。对函数的每次后续调用是否都使用第一次调用创建的相同内部缓冲区?

谢谢!

3 个答案:

答案 0 :(得分:2)

首先,printf()不直接处理缓冲区内存。假设它使用fwrite()函数调用(也使用系统调用write())将任何内容写入任何文件函数处理缓冲区内存。它包含一个pointer到下一个写入最后一个字符的位置。 fwrite()函数将数据写入特定文件。printf()请求fwrite()在名为stdout的特定文件中写入数据。

每次调用printf()函数时,都会调用fwrite()函数在stdout上写入数据。 假设您要打印"Hello World",可以通过printf

的单次调用进行打印
printf("Hello World\n");

OR

printf("Hello ");
printf("World");
printf("\n");

所以你可以用3 printf来调用它,这将调用fwrite() 3次,这个函数将记住接下来要写入数据的位置。例如: - 在最后一次调用{{ 1}}该位置将设置为下一行。

答案 1 :(得分:2)

你的问题是这个

printf("\t%d", i);
printf("\t\t%d", i * 2);
    // other printf elided for brevity

并不等同于您所寻求的。具体来说,您似乎认为错误每次printf()的调用都会将光标返回到行的开头(例如,在终端上)。

实际上,printf()的第二次调用在第一次打印的积分值之后立即写入,在同一行上。

输出是顺序的,所以

printf("\t%d", i);
printf("\t\t%d", i * 2);     // total of three \t in this and preceding statement

等同于(就完整数据输出而言)

printf("\t%d\t\t%d", i, i*2);    // note the 3 \t here.

不要

printf("\t%d\t%d", i, i*2);      //  only two \t here

此行为与缓冲无关。

答案 2 :(得分:0)

Printf的打印方式与您手动输入内容完全相同。除非你明确告诉它这样做,否则它不会回到行的开头。因此,当printf被要求打印" \ ta"和" \ tb"它首先输出

    a|
     ^- And leaves the "cursor" here...

所以当你要求它打印" \ tb"时,它会从它停止的地方恢复,然后打印:

    a    b