Reputation: 513
I have an integer in C language and I want to create a char array and insert the last digit each time using modulu 10. After that I need to print the array from end to beginning in order to get the number printed in the right order. I know it sounds weird, but I need to do it exactly like this.
But something is not working. The array is created fine, but than the char printing isn't working. This is what I did:
int baseChange (int base, int newBase, int num)
{
int baseTen = toBaseTen(base, num); //give me a number on base 10
char finalBase[24];
int i;
for (i = 0; baseTen != 0; i++)
{
int remain = baseTen % newBase;
finalBase[i] = (char)(remain); //insert the last digit to the array
baseTen /= newBase;
}
// Print finalBase from end to beginning in order to get the final number in the correct order:
for (i--; i >= 0; i--)
{
printf("i is: %d... %c", i, finalBase[i]);
}
return SUCCESS_EXIT;
}
If I print finalBase[i]
during the first for loop, I get the right numbers, but after that, the second for
loop is not printing anything. Why?
Upvotes: 0
Views: 653
Reputation: 5557
You are type casting Integer to Character, So it will consider your int
as a ASCII value of some character. And It will add that character to your array instead of your number. So try following:
int baseChange (int base, int newBase, int num)
{
int baseTen = toBaseTen(base, num); //give me a number on base 10
char finalBase[24];
int i;
for (i = 0; baseTen != 0; i++)
{
int remain = baseTen % newBase;
finalBase[i] = (char)(remain+48); //insert the last digit to the array
baseTen /= newBase;
}
// Print finalBase from end to beginning in order to get the final number in the correct order:
for (i--; i >= 0; i--)
{
printf("i is: %d... %c", i, finalBase[i]);
}
return SUCCESS_EXIT;
}
I've changed finalBase[i] = (char)(remain);
to finalBase[i] = (char)(remain+48);
.
Because numerics in ASCII starts with 48 so add 48 to every number you get in the loop, so that it can be converted to 0-9
. Thats it!
Second loop is not Printing anything WHY ?.
Because ASCII from 0-9 is not printable or are spaces and tabs.
Hope this will help you!
Upvotes: -1
Reputation: 5525
Needing assumptions about the encodings is always a source of trouble. Why not use a simple map? No assumptions about the encoding needed, you can even use the full Unicode range for the digits (Which would get a bit more complicated, although not that much).
#include <stdio.h>
#include <stdlib.h>
#define BC_OK 0
#define BC_ERROR_OB 1
#define BC_ERROR_NB 2
int baseChange(int, int, int);
int baseChange(int base, int newBase, int num)
{
// ASCII allows for up to base 64 without starting to get in trouble
// with characters used by others as special characters
// you can reuse this map for the inverse function, too.
const char *digits =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
int baseTen = num; //toBaseTen(base, num);
// 24 were not enough (max would be 2^64 in base two)
char finalBase[64];
int i, remain;
// always check the input
if (base < 2 || base > 64) {
return BC_ERROR_OB;
}
if (newBase < 2 || newBase > 64) {
return BC_ERROR_NB;
}
// Ignore sign?
// use shortcuts
if(num == 0){
i = 0;
finalBase[0] = '0';
} else {
for (i = 0; baseTen != 0; i++) {
remain = baseTen % newBase;
// cutting the two bytes off should not be necessary, just in case
finalBase[i] = digits[remain & 0xff];
baseTen /= newBase;
}
i--;
}
for (; i >= 0; i--) {
printf("i is: %d... %c\n", i, finalBase[i]);
}
return BC_OK;
}
// ALL CHECKS OMMITTED!
int main(int argc, char **argv)
{
int input;
int newbase;
int ret;
if (argc < 3) {
fprintf(stderr, "Usage: %s integer new_base\n", argv[0]);
exit(EXIT_FAILURE);
}
input = atoi(argv[1]);
newbase = atoi(argv[2]);
ret = baseChange(10, newbase, input);
if (ret != BC_OK) {
fprintf(stderr, "baseChange() failed with error number %d\n", ret);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
Upvotes: 0
Reputation: 2720
You are not converting your remain
to its ASCII code
when you are doing finalBase[i] = (char)(remain);
.
If your newBase
is <=10
, then your remainders are always in the range 0-9
, so to convert those number into their ASCII code you can do:
finalBase[i] = remain + '0'; // convert remain into its ASCII code
However, if your newBase is more than 10
, say hexadecimal, where remainders can be upto 15
then you need some more code.
Also, your loop does not check of you are inserting more than 24
elements to your array whose size is 24. So, you need to change:
/* Issue: You are not checking if you are going out ot bounds */
/* for (i = 0; baseTen != 0; i++) */
/* Confirm that you are in bounds, i.e. i < 24 */
for (i = 0; baseTen != 0 && i < 24 ; i++)
{
int remain = baseTen % newBase;
finalBase[i] = remain + '0'; //insert the last digit to the array
baseTen /= newBase;
}
/* To check if you went out of bound,
And also for case when your number is 0 */
if (i < 24)
finalBase[i++] = baseTen + '0';
/* Number too big to store in 24 characters */
else if (baseTen != 0) {
printf("Error: Number too large to store\n");
return;
}
Upvotes: 0
Reputation: 310930
For starters this loop
for (i = 0; baseTen != 0; i++)
{
int remain = baseTen % newBase;
finalBase[i] = (char)(remain); //insert the last digit to the array
baseTen /= newBase;
}
is incorrect because in general the value of the variable baseTen
can be initially equal to 0. In this case nothing will be written in the array.
The correct loop can look like
int i = 0;
do
{
finalBase[i++] = baseTen % newBase;
} while ( baseTen /= newBase );
As for the second loop where the digits should be displayed then you need to output corresponding representations of the digits as characters.
For example
while ( i-- )
{
printf( "i is: %d... %c\n", i, finalBase[i] + '0' );
^^^^^^^^^^^^^^^^^^^^^
}
Take into account that values of type int
can be negative. You should pay attention to write down negative values in the array.
Characters from '0'
through '9'
have sequential codes. So for example if to add 1
to character '0'
you will get character '1'
.
Or you could output the digits as integers. For example
while ( i-- )
{
printf( "i is: %d... %d\n", i, finalBase[i] );
^^
}
Or initially you could store the digits in the array as characters
int i = 0;
do
{
finalBase[i++] = '0' + baseTen % newBase;
} while ( baseTen /= newBase );
Upvotes: 1
Reputation: 6421
The cast from int
to char
is keeping the first CHAR_BIT
bits which are the the first 8 bits in the integer remain
and as the latter will contain digits (for modulo in base low than 10 of course), they will keep their values after casting.
Your problem is in printing the equivalent number in the ASCII table.
The %c
specifier in printf
function is refering to the character equivalent to the value in the ASCII Table and what holds the variable.
The first 10 characters refering to value 0
to 9
in ASCII table are equivalent to:
But the digits characters have the value from 48 to 57 (in base 10/decimal):
So instead of :
finalBase[i] = (char)remain;
You need to change it to:
finalBase[i] = remain + 48;
Upvotes: 2