【问题标题】:simulate ulltoa() with a radix/base of 36以 36 为基数/基数模拟 ulltoa()
【发布时间】:2011-08-28 01:28:11
【问题描述】:

我需要将一个无符号的 64 位整数转换为字符串。那是在 Base 36 或字符 0-Z 中。 Linux 联机帮助页中不存在 ulltoa。但是 sprintf 可以。如何使用 sprintf 来达到预期的效果?即什么格式的 % 东西?

或者如果 snprintf 不起作用,那我该怎么做呢?

【问题讨论】:

  • sprintf for unsigned _int64 的可能重复项
  • @Code 这是专门的base 36,我不认为这是一个dup。
  • 不要以为你可以使用 sprintf 来做到这一点

标签: c++ c printf itoa


【解决方案1】:

您始终可以编写自己的转换函数。以下想法是中偷来的,很大程度上受到this fine answer的启发:

char * int2base36(unsigned int n, char * buf, size_t buflen)
{
  static const char digits[] = "0123456789ABCDEFGHI...";

  if (buflen < 1) return NULL; // buffer too small!

  char * b = buf + buflen;
  *--b = 0;

  do {
    if (b == buf) return NULL; // buffer too small!

    *--b = digits[n % 36];
    n /= 36;
  } while(n);

  return b;
}

这将返回一个指向以空字符结尾的字符串的指针,该字符串包含n 的base36 表示,放置在您提供的缓冲区中。用法:

char buf[100];
std::cout << int2base36(37, buf, 100);

如果你愿意并且你是单线程的,你也可以将 char 缓冲区设为静态——我想你可以找出一个合适的最大长度:

char * int2base36_not_threadsafe(unsigned int n)
{
  static char buf[128];
  static const size_t buflen = 128;

  // rest as above

【讨论】:

  • 这假设缓冲区一开始就充满了NULLs。如果您有一个大小为 32 的缓冲区,并且您使用此函数并打印缓冲区并且缓冲区未充满空值,则它将打印最多为缓冲区大小(但不是更多)的错误字符数。
  • 此函数还接受unsigned int,这不是(我假设)32 位系统上的 64 位。应该是unsigned long long吧?
  • @Pete:公平地说,在我因提出基于malloc() 的解决方案而受到很多抨击之后,我几乎完全从this answer 那里窃取了这个想法。他们的方法要求您实际传递字符串的结尾,而我在这里选择在线程安全版本中使用开头加长度。不安全的版本当然更容易使用。我会添加学分!
  • @Seth:我不明白你的反对意见。我返回一个指向定义明确的字符串的指针,正确地以空值结尾。是的,在我的示例中,整数类型没有特定的宽度,但我相信 OP 能够根据需要对其进行修改。
  • @Kerrek 您更新的答案没有以前的问题。
猜你喜欢
  • 2016-01-13
  • 2019-09-02
  • 2017-02-09
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
相关资源
最近更新 更多