当前位置:  开发笔记 > 编程语言 > 正文

如何将复合文字用于`fprintf()`具有任意碱基的多个格式化数字?

如何解决《如何将复合文字用于`fprintf()`具有任意碱基的多个格式化数字?》经验,为你挑选了1个好方法。

我想将多个数字转换为某种表示形式,然后使用*printf()说明符的标志,宽度和精度.优先考虑避免全局或static缓冲.关键问题似乎是如何char[]为每个转换后的数字提供?

fprintf(ostream, "some_format", foo(int_a, base_x), foo(int_b, base_y), ...);

如何使用C11复合文字来解决这个问题?
如何使用C99(或更高版本)复合文字来解决这个问题?

chux - Reins.. 14

C99 C11引入了复合文字,它不仅允许复杂的初始化结构,而且还允许"在线"变量.

代码可以调用转换函数并(char [UTOA_BASE_N]){0}为每个函数调用传入一个新的缓冲区,允许函数返回相同的缓冲区,现在根据需要写入仍在其生命周期内的缓冲区.然后使用"%s"说明符可用的各种标志,宽度和精度打印返回的字符串.

#include 
#include 
#include 

// Maximum buffer size needed
#define UTOA_BASE_N (sizeof(unsigned)*CHAR_BIT + 1)

char *utoa_base(char *s, unsigned x, unsigned base) {
  s += UTOA_BASE_N - 1;
  *s = '\0';
  if (base >= 2 && base <= 36) {
    do {
      *(--s) = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[x % base];
      x /= base;
    } while (x);
  }
  return s;
}

#define TO_BASE(x,b) utoa_base((char [UTOA_BASE_N]){0} , (x), (b))

void test(unsigned x) {
  printf("base10:%10u base2:%5s  base36:%s ", x, TO_BASE(x, 2), TO_BASE(x, 36));
  printf("%lu\n", strtoul(TO_BASE(x, 36), NULL, 36));
}

int main(void) {
  test(0);
  test(25);
  test(UINT_MAX);
}

产量

base10:         0 base2:    0  base36:0 0
base10:        25 base2:11001  base36:P 25
base10:4294967295 base2:11111111111111111111111111111111  base36:1Z141Z3 4294967295

参考:是否有printf转换器以二进制格式打印?有许多答案,但没有一个允许上面的简单内存管理(否static)访问fprintf()标志宽度,精度和使用数字的整个范围.

这是一个回答你自己的问题的答案.



1> chux - Reins..:

C99 C11引入了复合文字,它不仅允许复杂的初始化结构,而且还允许"在线"变量.

代码可以调用转换函数并(char [UTOA_BASE_N]){0}为每个函数调用传入一个新的缓冲区,允许函数返回相同的缓冲区,现在根据需要写入仍在其生命周期内的缓冲区.然后使用"%s"说明符可用的各种标志,宽度和精度打印返回的字符串.

#include 
#include 
#include 

// Maximum buffer size needed
#define UTOA_BASE_N (sizeof(unsigned)*CHAR_BIT + 1)

char *utoa_base(char *s, unsigned x, unsigned base) {
  s += UTOA_BASE_N - 1;
  *s = '\0';
  if (base >= 2 && base <= 36) {
    do {
      *(--s) = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[x % base];
      x /= base;
    } while (x);
  }
  return s;
}

#define TO_BASE(x,b) utoa_base((char [UTOA_BASE_N]){0} , (x), (b))

void test(unsigned x) {
  printf("base10:%10u base2:%5s  base36:%s ", x, TO_BASE(x, 2), TO_BASE(x, 36));
  printf("%lu\n", strtoul(TO_BASE(x, 36), NULL, 36));
}

int main(void) {
  test(0);
  test(25);
  test(UINT_MAX);
}

产量

base10:         0 base2:    0  base36:0 0
base10:        25 base2:11001  base36:P 25
base10:4294967295 base2:11111111111111111111111111111111  base36:1Z141Z3 4294967295

参考:是否有printf转换器以二进制格式打印?有许多答案,但没有一个允许上面的简单内存管理(否static)访问fprintf()标志宽度,精度和使用数字的整个范围.

这是一个回答你自己的问题的答案.


是的,是的,是的,这个答案(的例子)说明为什么我们应该喜欢复合*文字*!;-)
推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有