sprintf在C中引领零填充

问题描述 投票:2回答:6

下面的代码打印ffffffffff

我需要输出为16位数长000000ffffffffff与前导零。 var1var2变量可能不同,因此我不需要仅填充6个零。我只需要输出带有前导零的16位数字。我该怎么办?

#include <stdio.h>

int main() {
    int var1 = 1048575;
    int var2 = 1048575;

    char buffer[100];

    sprintf(buffer, "%x%x", var1, var2);
    printf("%s\n", buffer);

    return 0;
}
c printf
6个回答
1
投票

你可以分两步完成:

#include <stdio.h>

int main(void) {
    int var1 = 1048575;
    int var2 = 1048575;
    int length = 0;
    char buffer[100];
    char paddedbuffer[100] = "000000000000000";
    length = sprintf (buffer, "%x%x", var1, var2);
    char* here = length < 16 ? paddedbuffer + 16 - length : paddedbuffer;
    sprintf(here, "%s", buffer);
    printf("%s\n", paddedbuffer);
    return 0;
}

某处可能有更优雅的解决方案。

另一种可能性是将结果转换为整数并使用字段宽度进行sprintfing,或者首先计算最右边数字的实际数字。


1
投票
#include <stdio.h>

int main ()
{
    int var1=1048575;
    int var2=1048575;

    char buffer [17];
    char zeros [] = "0000000000000000";    
    sprintf (buffer, "%x%x", var1, var2);

    // Put the zeros in front
    int len = strlen(buffer);
    if (len < 16)
    {
        zeros[16-len] = 0x0; // Terminate the string at 16-len
    }
    else
    {
        zeros[0] = 0x0;  // Terminate the string at 0 as no extra zero is needed
    }

    printf("%s%s\n", zeros, buffer);

    return 0;
}

1
投票

这是一个没有中间缓冲区的简单解决方案:

#include <stdio.h>

int main(void) {
    int var1 = 1048575;
    int var2 = 1048575;

    printf("%0*x%x\n", 16 - snprintf(NULL, 0, "%x", var2), var1, var2);

    return 0;
}

有一种特殊情况,您可能想要定义精确的行为:如果var2 == 0怎么办?上面的代码将打印一个尾随0。如果您只想打印有效数字,因此零值没有数字,您可以这样修改语句:

    printf("%0*x%x\n", 16 - snprintf(NULL, 0, "%.x", var2), var1, var2);

一个小差异:在.%之间添加一个x来指定0的精度字段,指定最小位数为无。


0
投票

使用tmp缓冲区和'0's的字符串(char数组)的另一个轻微的转折:

#include <stdio.h>
#include <string.h>

enum { PADLN = 16, MAXC = 17 };

int main (void)
{
    int var1=1048575;
    int var2=1048575;

    char tmp [MAXC];
    char buffer [MAXC];
    char zeros[] = "0000000000000000";
    size_t len = 0;

    sprintf (tmp, "%x%x", var1, var2);
    len = strlen(tmp);
    zeros[PADLN - (len < PADLN ? len : PADLN)] = 0;
    sprintf (buffer, "%s%s", zeros, tmp);

    printf ("\n buffer : '%s'\n\n", buffer);

    return 0;
}

产量

$ ./bin/pad16

 buffer : '000000ffffffffff'

0
投票

打印var2然后打印连接

#include <stdio.h>

int main(void) {
  int var1 = 1048575;
  int var2 = 1048575;

  char buffer[100];
  char bufvar2[sizeof var2 * CHAR_BIT + 1];
  int len = sprintf(bufvar2, "%x", var2);

  #define TOTAL_MIN_WIDTH 16
  sprintf(buffer, "%0*x%s", TOTAL_MIN_WIDTH - len, var1, bufvar2);
  printf("%s\n", buffer);

  return 0;
}

0
投票

您还可以执行一些小的微积分来计算有效位数,然后打印所需的前导零数,因为log_base_ 16(var)是以十六进制表示的var的大小:

#include <stdio.h>
#include <math.h>

int main ()
{
    int var1 = 1048575;
    int var2 = 1048575;
    int padd = 16 - ceil(log(var1)/log(16))-ceil(log(var2)/log(16));
    char buffer [100];
    sprintf (buffer, "%0*x%x%x", padd, 0, var1, var2);
    printf("%s\n", buffer);

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.