这是安全还是UB?
char x[5] = { 'a', 'b', 'c', 'd', 'e' };
printf("%5.5s\n", x);
Run Code Online (Sandbox Code Playgroud)
打印非零终止字符串的正确 printf 格式是什么?(或者打印 c 字符串的前 N 个字符的格式是什么?)
行为定义明确。与普通%s转换说明符对应的参数必须是指向字符串的指针(根据定义,这意味着它包含空'\0'终止符),但如果指定了精度,则参数不必是指向字符串的指针(即,只要数组足够长,就没有空终止符)。
引用 C11 标准草案,N1570 7.21.6.1p8:
数组中的字符被写入(但不包括)终止空字符。如果指定了精度,则写入的字节数不会超过该数量。如果精度未指定或大于数组的大小,则数组应包含空字符。
如果要打印字符数组的前 N 个字符,其中 N 不是常量,则可以使用 a*指定长度作为单独的参数给出。例如,给定一个已知长度且不包含空字符的字符数组,您可以执行以下操作:
const char s[5] = "hello"; /* no terminating null character */
printf("%.*s\n", (int)sizeof s, s);
Run Code Online (Sandbox Code Playgroud)
请注意,sizeof仅在此处有效,因为它s是一个数组;如果它是一个指针,sizeof会给你一个指针的大小,而不是数组的大小。另请注意,*需要一个类型为 的参数int;由于printf是一个可变参数函数,并sizeof产生一个 type 值,size_t在这种情况下你需要强制转换。
| 归档时间: |
|
| 查看次数: |
1033 次 |
| 最近记录: |