I have this function which receives the number 894867
(nbr
) and the length 16
(i
). When I run this code, it writes =A793
instead of what it should write DA793
.
void ft_transformers(int nbr, int i) {
char num[100];
int t;
int temp;
int j;
temp = 0;
t = 0;
while (nbr != 0) {
temp = nbr % i;
if (num[t] < 10) {
num[t] = temp 48;
} else {
num[t] = temp 55;
}
nbr /= i;
t ;
}
j = t;
while (j >= 0) {
ft_putchar(num[j]);
j--;
}
}
CodePudding user response:
There are multiple problems:
Instead of
if (num[t] < 10)
, you should be testingif (temp < 10)
instead of hardcoding ASCII values such as
48
and55
, you should use character constants and expressions'0'
and'A' - 10
the final loop should decrement
j
before accessing the character in the array.the behavior is undefined if
i
is0
,1
or-1
.
Here is a modified version:
void ft_transformers(int nbr, int base) {
char num[100];
int t;
int j;
if (base < 2 || base > 36)
base = 10;
t = 0;
while (nbr != 0) {
int temp = nbr % base;
if (temp < 10) {
num[t] = '0' temp;
} else {
num[t] = 'A' (temp - 10);
}
nbr /= base;
t ;
}
j = t;
while (j > 0) {
j--;
ft_putchar(num[j]);
}
}
Note also these shortcomings:
the function will not output anything if the initial value of
nbr
is zero.the function will not output digits if
nbr
is negative.
Here is an improved version:
void ft_transformers(int nbr, int base) {
char num[100];
int t;
int j;
int isneg;
if (base < 2 || base > 36)
base = 10;
isneg = 0;
t = 0;
for (;;) {
int temp = nbr % base;
if (temp < 0) {
isneg = 1;
temp = -temp;
}
if (temp < 10) {
num[t] = '0' temp;
} else {
num[t] = 'A' (temp - 10);
}
t ;
nbr /= base;
if (nbr == 0)
break;
}
if (isneg) {
ft_putchar('-');
}
j = t;
while (j > 0) {
j--;
ft_putchar(num[j]);
}
}
CodePudding user response:
Your code has two errors:
- The condition
num[t] < 10
is wrong.num[t]
is uninitialized at that point. It should betemp < 10
. - The initialization of the second loop
j = t;
is wrong.t ;
is executed at the end of the first loop and nothing is written tonum[t]
after that before the second loop. It should bej = t - 1;
.
Also using magic numbers like 48
and 55
should be avoided. They should be '0'
and 'A' - 10
to make it more clear. (unless your code has chance to be used in environments where character sets that are not compatible to ASCII are used)
CodePudding user response:
There are at least three drawbacks in the function.
For starters instead of the while loop you have to use do-while loop. Otherwise if nbr
initially is equal to 0 the function will have undefined behavior.
Secondly, in this if statement
if (num[t] < 10) {
you have to use the variable temp
instead of num[t]
if ( temp < 10) {
After the while loop the variable t points to after the last digit of the number. So in the first iteration of this loop
j = t;
while (j >= 0) {
ft_putchar(num[j]);
j--;
}
there will be outputted an indeterminate value.
T least you should write
j = t;
while (j != 0) {
ft_putchar(num[--j]);
}
Pay also attention to that your function ignores the sign of the original number.
And it is a bad idea to use magic numbers like for example 48
or 55
.
The function can be declared the following way as it is shown in the demonstration program be.low.
#include <stdio.h>
void ft_transformers( int nbr, int base )
{
if ( base < 2 || base > 36 )
{
printf( "%d\n", nbr );
}
else
{
char num[8 * sizeof( int )];
int sign = nbr < 0;
size_t i = 0;
do
{
int digit = nbr % base;
if ( sign ) digit = -digit;
if ( digit < 10 )
{
digit = '0';
}
else
{
digit = digit - 10 'A';
}
num[i ] = digit;
} while ( nbr /= base );
if ( sign ) putchar( '-' );
while ( i != 0 ) putchar( num[--i] );
putchar( '\n' );
}
}
int main( void )
{
int nbr = 0;
ft_transformers( nbr, 16 );
nbr = 894867;
ft_transformers( nbr, 16 );
nbr = -894867;
ft_transformers( nbr, 16 );
}
The program output is
0
DA793
-DA793
In this declaration of the character array
char num[8 * sizeof( int )];
instead of the number 8 (the number of bits in a character) you can use the constant CHAR_BIT like
char num[CHAR_BIT * sizeof( int )];
To do so you need to include the header <limits.h>
.