printf()的字符串宽度是否安全,没有未终止的字符串?

时间:2016-01-12 16:47:44

标签: c printf language-lawyer undefined-behavior

以下是否定义明确?

const char not_a_c_string[] = { 'h', 'e', 'l', 'l', 'o' };
printf( "%.5s", (const char*) not_a_c_string );

这是关于特定表单"%.5s"的问题,而不是如何打印可能不是NUL终止的字符串?,因为此问题有already been answered here其中{建议{1}}构造。

1 个答案:

答案 0 :(得分:11)

首先,我相信,您打算询问精度,而不是字段宽度。所以,你的例子看起来像是

 printf( "%.5s", (const char*) not_a_c_string );  //precision

而不是

 printf( "%5s", (const char*) not_a_c_string );   //field width.

考虑到上述方法,不,在你的例子中它不会是UB。

引用C11标准,章节§7.21.6.1, fprintf函数,第8段,(强调我的

  

s如果不存在l长度修饰符,则参数应为指向初始值的指针   字符类型数组的元素。(280)数组中的字符是   写入(但不包括)终止空字符。如果   指定精度,不超过写入的多个字节。 如果   精度未指定或大于数组的大小,数组应   包含空字符。

所以,只有当你要么

时才需要有一个空分隔数组( string
  • 缺少精确度
  • 提供的精度是>提供的char数组的大小。

在您的情况下,提到的精度(5)不大于数组的大小(也是5)。所以,没关系。

FWIW,如果示例仍然是

 printf( "%5s", (const char*) not_a_c_string );

那么它将是UB,因为你将缺少那里的精度。