如何使用复合文字对任意基数的多个格式化数字执行fprintf()? [英] How to use compound literals to `fprintf()` multiple formatted numbers with arbitrary bases?

查看:90
本文介绍了如何使用复合文字对任意基数的多个格式化数字执行fprintf()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to convert multiple numbers into some representation and then use the flags, width and precision of *printf() specifiers. Preference would be to avoid global or static buffers. The key problem appears to be is how to provide a char[] for each of the converted numbers?

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

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

How to use C11 compound literals to solve this?
How to use C99 (or later) compound literals to solve this?

推荐答案

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

C99 C11 introduced compound literals which allow not only a complicated initialized structure, but also an "in-line" variable.

代码可以调用转换函数,并在每次函数调用时传递新的缓冲区(char [UTOA_BASE_N]){0},从而使该函数返回相同的缓冲区,现在根据需要编写该缓冲区,而仍在其生存期内.然后使用"%s"说明符可用的各种标志,宽度和精度来打印返回的字符串.

Code can call a conversion function and pass in a new buffer (char [UTOA_BASE_N]){0} per each function call allowing the function to return that same buffer, now written as needed that is still within its lifetime. The returned string is then printed using various flags, width and precision available to the "%s" specifier.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

// 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()标志的宽度,精度并使用数字的整个范围.

Ref: Is there a printf converter to print in binary format? has a number of answers but none of them allow the simple memory management (no static) of the above with access to fprintf() flags width, precision and use the full range of the number.

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

这篇关于如何使用复合文字对任意基数的多个格式化数字执行fprintf()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆