Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 威尔';printf';总是做它的工作吗?_C_Printf - Fatal编程技术网

C 威尔';printf';总是做它的工作吗?

C 威尔';printf';总是做它的工作吗?,c,printf,C,Printf,我知道printf()使用一个缓冲区,当缓冲区函数看到行缓冲区中的“\n”时,它会打印它包含的任何内容。因此,当我们忘记在printf()中使用“\n”时,行缓冲区很少不会被清空。因此,printf()无法完成它的工作。我错了吗?您上面给出的示例是安全的,因为printf没有变量参数。但是,可以指定格式字符串并提供与格式不匹配的变量,这可能会产生意外(且不安全)的结果。一些编译器在使用printf用例分析时采取了更主动的方法,但即使如此,在使用printf时也应该非常非常小心。像这样,不。它不会

我知道printf()使用一个缓冲区,当缓冲区函数看到行缓冲区中的“\n”时,它会打印它包含的任何内容。因此,当我们忘记在printf()中使用“\n”时,行缓冲区很少不会被清空。因此,printf()无法完成它的工作。我错了吗?

您上面给出的示例是安全的,因为
printf
没有变量参数。但是,可以指定格式字符串并提供与格式不匹配的变量,这可能会产生意外(且不安全)的结果。一些编译器在使用
printf
用例分析时采取了更主动的方法,但即使如此,在使用
printf
时也应该非常非常小心。

像这样,不。它不会总是像您预期的那样工作,特别是当您使用用户输入作为格式字符串时。如果第一个参数中有%s或%d或其他格式说明符,它们将被解析并替换为堆栈中的值,如果它需要一个指针而不是一个int,则很容易中断

这种方式往往更安全:

printf("/*something else*/"); /*note that:without using \n in printf*/
输出缓冲区将在退出之前或在您获得输入之前刷新,因此无论您是否发送\n

从我的手册页:

这些函数返回打印的字符数(不包括 尾随的
\0
用于结束输出(字符串)或负值 如果出现输出错误,除了
snprintf()
vsnprintf()
,这两种错误 返回如果n 是无限的(同样,不包括最后的
\0


因此,这听起来像是由于一个负面错误而失败。

printf
可能由于多种原因而失败。如果深入递归,调用
printf
可能会导致堆栈崩溃。C和C++标准在线程问题上没有什么可说的,调用<代码> Prtff<代码>,而代码“Prtff<代码>在另一个线程中执行可能失败。它可能会失败,因为
stdout
附加到一个文件,而您刚刚填充了文件系统,在这种情况下,返回值告诉您有问题。如果调用
printf
时使用的字符串不是以零结尾的,则可能会发生不好的事情。如果您使用的是缓冲I/O,而您的缓冲区尚未刷新,则
printf
显然可能会失败。

是的,C中
stdout
的输出(使用
printf
)通常是行缓冲的。这意味着
printf()
将收集输出,直到:

  • 缓冲区已满,或
  • 输出包含一个
    \n
    换行符

如果要强制输出缓冲区,请调用
fflush(stdout)
。即使您打印的内容没有换行符,这也会起作用。

printf和friends也可能失败

stdC库的printf系列中C调用malloc()的常见实现。
malloc可能会失败,printf也会失败。在UNIX中,write()调用可能会被EINTR中断,因此UNIX中的上下文切换将触发故障(EINTR)。Windows可以也将做类似的事情


而且。。。虽然您不经常在这里看到它,但是您应该始终检查任何系统或库函数返回值的返回代码

我不知道你想问什么。你能把你的问题解释清楚吗?“安全且始终工作”是什么意思?好的,从您的问题更新来看,听起来您想阅读有关行缓冲的内容……是的,
printf
将始终完成它的工作。但它的部分工作是缓冲数据,
stdout
通常是行缓冲的。因此,如果没有
\n
,数据可能不会被刷新,但在缓冲区中是安全的。如果您需要在换行前刷新缓冲区,您只需调用
fflush(stdout)
fprintf
fwrite
等,就不会出现信号问题,因为对于所有执行temrinal、socket、file等操作的printf函数,基本系统调用都是write()。写入将由于信号而失败,例如EINTR。写不是原子的。例如,请参见:“另一点-这是glibc基本模块代码(vfprintf)-cse在点malloc:workstart=(CHAR_T*)malloc((width+32)*sizeof(CHAR_T));if(workstart==NULL){done=-1;转到all_done;}意思是:[无论哪个]printf()在malloc失败时将失败。
printf("%s", "....");