C 如何在没有printf的情况下打印ULONG_MAX

C 如何在没有printf的情况下打印ULONG_MAX,c,limits,C,Limits,我正在重新编写printf函数。问题在于限制,例如,我无法打印ULONG_MAX number printf("%lu", ULONG_MAX) gives me ->18446744073709551615 ft_putnbr(ULONG_MAX) gives me -> -1 我包括以下两个库: <limits.h> <locale.h> 我的putnbr是这样一个基本的递归函数(适用于其他数字): void ft_putnbr(内部编号) { i

我正在重新编写printf函数。问题在于限制,例如,我无法打印ULONG_MAX number

printf("%lu", ULONG_MAX) gives me ->18446744073709551615

ft_putnbr(ULONG_MAX) gives me -> -1
我包括以下两个库:

<limits.h> 
<locale.h>
我的putnbr是这样一个基本的递归函数(适用于其他数字):

void ft_putnbr(内部编号)
{
if(nb<0)
{
ft_putchar('-');
nb=-nb;
}
如果(nb>=10)
{
布丁布尔堡(nb/10);
英尺/平方英尺(nb%10);
}
其他的
{
ft_putchar(nb+'0');
}
}

任何帮助都将不胜感激

由于代码中似乎隐藏了一个太长而无法显示的bug,我建议您回到以前的调试


提示:int类型的参数不能保存unsigned long类型的所有值

首先要检查
nb
是否小于
0

对于
ULONG_MAX
nb
作为
int
传递,而不是
unsigned int
),这是正确的,因此您选择第一个分支

打印
“-”
,然后将
-1
转到
1


在最后一次迭代中,只打印字符
1

错误在于
ft\u putnbr()
函数采用
int
参数。当您向它传递一个类型为
unsigned long
的变量时,有两个问题。两者都可以使用此代码段进行复制:

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

int main() {
    unsigned long my_long = ULONG_MAX;
    int my_int = (int) my_long;
    printf("%lu\n", my_long);
    printf("%i\n", my_int);
}
#包括
#包括
int main(){
未签名的long my_long=ULONG_MAX;
int my_int=(int)my_long;
printf(“%lu\n”,my_long);
printf(“%i\n”,my\u int);
}
第一个问题是,参数的长度比您尝试传递给函数的值短。让我们假设
long
在我们的系统上是2个字节,而
int
是1个字节(更现实地说,它们应该是4或8个字节)。在二进制中,
ULONG_MAX
将是
1111111111111111
。但是,当将其分配给仅为1字节的
int
时,该值将为
1111111
,因为只有8位的空间。为了传递
ULONG_MAX
,我们需要一种长度相同(或更大)的类型,以便为所有位留出空间。例如,我们可以使用
long
,使函数签名变成
ft_putnbr(long nb)

然而,还有一个问题。类型
long
是有符号的(即其中一个位专用于跟踪数字是负数还是正数),而
ULONG_MAX
是无符号类型(即仅正数)。特别是,如果第一位为1,则表示该数字为负数。因此,二进制值为
1111111111111111111
的有符号2字节类型将为负。它变为(十进制)
-1
的原因超出了这个答案(但您可以在此处阅读:)


那么,我们如何解决这两个问题呢?一种方法是让
ft_putnbr()
采用非常宽的有符号类型(例如,
long-long
),并且从不传递任何长度相等或更大的无符号类型。另一种方法是编写两个
ft\u putnbr()
(使用不同的名称):一个采用最宽的有符号类型,另一个采用最宽的无符号类型。

好的,多亏了你们,我使这两个限制(LONG\u MAX和LONG\u MIN)都有效:

void ft_putnbr(long-long-int-nb)
{
如果(nb==长_MIN)
金融时报(“9223372036854775808”);
如果(nb<0&&nb!=LONG\u MIN)
{
ft_putchar('-');
nb=-nb;
}
如果(nb>=10&&nb!=LONG\u MIN)
{
布丁布尔堡(nb/10);
英尺/平方英尺(nb%10);
}
否则如果(注意!=长时间)
{
ft_putchar(nb+'0');
}
}

显示
ft\u myprintf()
的定义,并将其添加到问题中。并添加ft_nb_arg、ft_print_it以及您调用的其他内容。你认为人们能读懂你的心思吗?这是我的代码:你的
ft\u putnbr()
函数接受一个
int
参数。这怎么能保持ULONG_MAX?好的,我现在就改变它,然后尝试,但我不认为它会成功…我编辑了主题,我只尝试用我的put_nbr显示这个数字,这就是全部,谢谢你,它成功了!!为了获得最大值,我必须传递一个无符号的long-long-int!!
void    ft_putnbr(int nb)
{
    if (nb < 0)
    {
        ft_putchar('-');
        nb = -nb;
    }
    if (nb >= 10)
    {
        ft_putnbr(nb / 10);
        ft_putnbr(nb % 10);
    }
    else
    {
        ft_putchar(nb + '0');
    }
}
#include <limits.h>
#include <stdio.h>

int main() {
    unsigned long my_long = ULONG_MAX;
    int my_int = (int) my_long;
    printf("%lu\n", my_long);
    printf("%i\n", my_int);
}
void    ft_putnbr(long long int nb)
{
    if (nb == LONG_MIN)
        ft_putstr("-9223372036854775808");
    if (nb < 0 && nb != LONG_MIN)
    {
        ft_putchar('-');
        nb = -nb;
    }
    if (nb >= 10 && nb != LONG_MIN)
    {
        ft_putnbr(nb / 10);
        ft_putnbr(nb % 10);
    }
    else if (nb != LONG_MIN)
    {
        ft_putchar(nb + '0');
    }
}