首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在没有stdlib的C中将数字打印为字符串

在没有stdlib的C中将数字打印为字符串
EN

Stack Overflow用户
提问于 2021-10-23 14:56:00
回答 3查看 69关注 0票数 0

这个问题是来自Unix & Linux Stack Exchange的migrated,因为它可以在堆栈溢出上得到回答。上个月在Migrated上。

我正在尝试做一些类似于printf("My age is: %d\n", age);的事情,但是我没有访问标准库的权限。相反,我可以访问的打印函数print()只接受一个const char*

我不允许使用sprintfitoa或任何类似的东西,因为它们根本不可用。有没有办法把号码打印出来?

附注:如果您需要更多上下文,https://github.com/SpinalHDL/VexRiscv/issues/215是:)

提前感谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-23 15:12:13

它有点笨拙。您可以从低端开始获取数字,使用% 10 (模数)分隔单位数字,使用/ 10 (整数除)将数字向右移位。你在一个循环中这样做,直到int降到零。如果整件事是零,你必须自己设置'0‘字符,因为循环不会进行第一次迭代。

您需要将'0‘添加到每个数字以使其成为ASCII数字,并且您需要将连续的数字存储在char数组中。

您需要在末尾追加NUL ('\0')字符作为字符串终止符。

然后你需要颠倒整个字符串,因为数字是以相反的顺序出现的。或者,您可以从末尾填充char数组,但随后必须将整个字符串(包括NUL)复制到缓冲区的前面。

如果整数可以是负的,你需要记住这一点,通过从零中减去它来使它为正,并在反转它之前在末尾粘贴一个'-‘。

听起来很多,但是long2str函数需要大约20行代码。

编辑:也有一个递归的解决方案。沿着所需的深度向下走,并在返回时保存数字,可以避免逆序问题(包括减号),并创建没有填充的字符串。

代码语言:javascript
复制
//.. Recursive solution.

//.. Base case.

void l2s_r (char **p, long int n)

{
    char d = (n % 10) + '0';
    if (n >= 10) l2s_r (p, n / 10);
    *((*p)++) = d;
}

//.. Wrapper case.

char *l2s (long int n)

{
static char s[24];
char *p = s;

    if (n < 0) { *p++ = '-'; n = 0 - n; }
    l2s_r (& p, n);
    *p = '\0';
    return (s);
}
票数 4
EN

Stack Overflow用户

发布于 2021-10-30 05:29:53

像这样的东西

代码语言:javascript
复制
int length(long long int no) 
{
 int count = 0;
 while (no != 0) 
 {
    no = no/10;
        count++;
 }
 return count;
}

void printer(long long int no)
{
   long long int temp = no;
   int i=0;
   char arr[10000];    
   i = length(no)-1;
   //Extract digits and fill `arr` backwards
   while(temp > 0)
   {
        arr[i] = (temp%10 + '0');    
        i--;
        temp = temp/10;
   }
   arr[length(no)] = '\n'; 
  char* p = &arr[0];
  println(p); //specific to: https://github.com/SpinalHDL/VexRiscv/blob/master/src/main/c/murax/hello_world/src/main.c
  //return p;
}
票数 0
EN

Stack Overflow用户

发布于 2021-10-30 12:20:49

由于已经过去了一周,(我不喜欢为深夜硬件任务提供代码),所以一些代码来补充@Paul_Pedant描述性答案。

从2到36的一种方法,从右到左形成数字字符串。

它通过形成负的绝对值来避免0 - INT_MIN的未定义行为。

它使用div()而不是/, %来避免C89的实现行为。

由于使用了do循环,因此print_int(0, base)打印"0"

代码语言:javascript
复制
#include <assert.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
extern int print(const char *);

// Enough room for INT_MIN as a binary string.
#define MY_ITOA_BUF_SIZE (sizeof(int)*CHAR_BIT + 2)
#define MY_ITOA_BASE_MIN 2
#define MY_ITOA_BASE_MAX 36

// Negative values result in a string beginning with a '-' for all bases.
// Adjust as desired.
void print_int(int i, int base) {
  char buf[MY_ITOA_BUF_SIZE];
  char *p = &buf[sizeof buf - 1]; // Start from the "right".
  assert(base >= MY_ITOA_BASE_MIN && base <= MY_ITOA_BASE_MAX);

  *p = '\0';
  int value = i < 0 ? i : -i;  // negative absolute value
  do {
    div_t qr = div(value, base);
    *(--p) = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-qr.rem];  // Table look up
    value = qr.quot;
  } while (value);

  if (i < 0) {
    *(--p) = '-';
  }

  print(p);  // Like fputs(p, stdout)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69779184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档