Linux:打印指定长度的零填充字符串

Dr.*_*ana 3 c format-specifiers

在Linux上,我正在使用GNU gcc 4.9.2版本,并在尝试打印指定长度的零填充字符串时出现奇怪的意外行为.这是我正在尝试的代码段:

#include <cstdio>
#include <cstring>
int main()
{
  char buff[5];
  sprintf(buff,"%04s","12");
  printf("%s\n", buff);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

虽然http://www.cplusplus.com/reference/cstdio/printf/中给出的文档清楚地指出,当指定填充时,标志左边用数字填充(0)而不是空格.但是,它的打印空间填充"12"即"12"而不是"0012".补救?

And*_*ing 5

printf联机帮助页中,您将找到一个确切的解释:

0

该值应为零填充.为d,i,o,u,x,X,a,A,e,E,f,F,g,和G转换,转换后的值被填充在左边用零而不是空白.[...]对于其他转换,行为未定义.

因此,它没有为字符串定义.实现可以填充0但不必.这是未定义的行为.

以下解决方案使用%.*s语法作为格式说明符,因此不需要使用for循环或多个printf调用.

char buff[5];
char str[] = "12";
size_t len = strlen(str);
sprintf(buff, "%.*s%s", len >= 4 ? 0 : (int)(4 - len), "0000", str);
Run Code Online (Sandbox Code Playgroud)

此外,您应该考虑使用snprintf以防止缓冲区溢出.

snprintf(buff, sizeof(buff), "%.*s%s", len >= 4 ? 0 : (int)(4 - len), "0000", str);
Run Code Online (Sandbox Code Playgroud)

格式化的输出snprintf可能与不同的编译器有所不同.在Linux gcc下,它总是附加一个尾随空字节'\0'.如果要写入的字符串大于或等于缓冲区,则Visual Studio 2010编译器无法确保.

  • 更简单的解决方案:`sprintf(buff,"%s%s","0000"+(len> 4?4:len),str);` (3认同)