Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
274 views
in Technique[技术] by (71.8m points)

c - How to use compound literals to `fprintf()` multiple formatted numbers with arbitrary bases?

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), ...);

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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 = '';
  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
", strtoul(TO_BASE(x, 36), NULL, 36));
}

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

Output

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

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.

This is an Answer your own question answer.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...