Converting a number in one base to another base using recursion - c

So im having trouble with creating a recursive function to convert a number from bases 2-10 to bases 2-16. I need it to return a string (obviously , due to the bases greater than 10).
here is my function:
main would call it like:
answer = baseConversion(101, 10, 2);
I have hex as a constant char:
const char Hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char * baseConverter(int number,int currbase, int base){
if(currbase != 10){
number = base10Converter(number, currbase); //converts the number to base of 10
currbase = 10;
}
if(number == 0 || base==10){
return number;
}
int r = number%base;
printf("%c", Hex[r]);
//return (number % base) + 10*baseConverter(number /base, currbase, base); // this gives the answer as an integer.
return Hex[r]+ && baseConverter(number /base, currbase, base) // I dont know what to add here to add the characters together
}
i need help with my return statement and recursive call.
Do i need to declare a char array within the function and then append the chars i get from hex[r] to it? If so, How do i go about doing that because I cant change the parameters

ints done't have bases, they just have values. How you display, or represent with a string, have bases. Thus, it doesn't make sense to have a currBase, unless you started with a string representation of the value you want to convert.
baseConverter, is defined so that it returns a string; since it is not passed space for that string, it will have to allocate it.
Thus, for the recursive case, you'd call baseConverter to give you a string for the rest of the number, and use that to make a new string (which you need to allocate), being sure to deallocate the string you got from the recursive call when you are done.

Related

Access and store value by index in a pointer

I've got an assignment where I have to sum whole numbers up to 100 digits.
They gave me this struct to represent big numbers (I think there are better ways to represent this, but I'm not allowed to modify it):
typedef struct {
char* string;
int lengthError;
} BigNumber;
Where string is the number itself and lengthError is the length of the number or an error that is a previously defined enum.
I've also have the implementation of the sum function
BigNumber *sum(BigNumber* num1, BigNumber* num2) {
BigNumber* result = malloc(sizeof(BigNumber));
int limit = getLength(num1->lengthError, num2->lengthError);
result->string = malloc(limit);
int digitResult;
int index = limit -1;
int carry = 0;
while(index != -1) {
int d1 = ((int)num1->string[index]) - ((int)'0');
int d2 = ((int)num2->string[index]) - ((int)'0');
digitResult = d1 + d2 + carry;
if (digitResult > 9) {
digitResult = digitResult - 10;
carry = 1;
} else {
carry = 0;
}
itoa(digitResult, &result->string[index], 10); //I think this is the problem
index--;
}
result->string[limit] = '\0';
printf("result: %s\n", result->string);
return result;
}
I haven't finished writing that function, I know there are a lot of flaws in it, but the problem is that I can't get to sum 12 + 12. The result I get is 2.
I thought approaching this problem by picking the lasts character of both numbers, transform them into an int and sum them having in mind the carry digit. After I got the result in digitResult I try to convert it to a char and store it in the corresponding position of the result->string pointer
Once it has finished the operation, I add an \0 at the last position of the result->string.
So the question is, how do I make this operation to work as desired? Debugging the code, I noticed that the first time it stores the first result in result->string, following the example above this would be a number 4, it stores trash in that position instead. In the second addition, I store a number 2 correctly and that's the final result I get in when I print the result.
Your use of the itoa function is a problem (though, as you have also suggested, maybe not the only one).
The itoa function converts its first argument into a null-terminated string - so, as well as writing the character representation of digitResult at the indicated place in the string, it also adds a '\0' character after it. Thus, your string will always be terminated immediately after the last digit you write, and 12 + 12, giving 24 will appear to be just the first character: 2.
What you can do instead is to convert the digit yourself (reversing the operation you used to get the d1 and d2 values), then just directly set the string element to the converted digit.
So, instead of:
itoa(digitResult, &result->string[index], 10);
use:
result->string[index] = (char)(digitResult + '0');

How to print contact number as one by one without using looping and default conversion?

Example : My contact number is 9876543210. We will save this number as either as integer or longInt as we know. Actually i need to print my contact number as one by one without any conversion (Int -> String) and do not use looping.
If you are still stuck on how to approach a recusive function, start with understanding that every recursive function has 2-parts:
1 A Base-Case which is the condition that is checked to determine when the recursion should end; and
2 A Recursive Call (meaning the function calls itself).
In your case of extracting the digits from a number, you simply want to extracts the first digit with number % 10 which will isolate the least significant base-10 digit. Then you want to divide the number by 10 and repeat.
Where you would normally repeat by calling the modulo and division in a loop, here you want to make a separate function call passing the result of number / 10 as the new parameter to your function.
You continue until your Base-Case is satisfied, and then the recursion begins to unwind where you return from the deepest function where you reach your Base-Case back into the previous function call -- and all the way back to the original. Careful placement of your outputting of the ASCII character for that digit will allow the numbers to be printed in-order.
A very minimal recursive function to do this could look like:
#include <stdio.h>
void prnnum (int n)
{
if (n == 0) /* base-case, when n==0, stop recursion */
return;
int digit = n % 10; /* save digit to print */
prnnum (n / 10); /* make recursive call */
putchar (digit + '0'); /* output ASCII value of digit on return */
}
(thinking though what may be needed to accommodate negative values, if anything, etc.. is left to you)
You can add a short main() that lets you pass in different numbers to test, e.g.
int main (int argc, char **argv) {
int n = 54321;
if (argc > 1 && sscanf (argv[1], "%d", &n) != 1)
return 1;
prnnum (n);
putchar ('\n');
}
Example Use/Output
Running without any command line input using the default value for n = 54321;, you receive:
$ ./bin/recursiveprnnum
54321
Passing in another number as the 1st argument you could do:
$ ./bin/recursiveprnnum 9378456
9378456
And in each case the digits have been printed one digit at a time and without a loop. Look things over and let me know if you have further questions.
You can also do this with using pointers but taking modulus of number by 10 is the easiest method but it has limitations. If you have + at the start of the number then this method will not work as it only deals with digit..So my method will work for both cases.
#include <stdio.h>
// Function Prototype
void printNum(char *num);
int main(){
// Creating a pointer, pointing
// toward your number or anyother array
char *num = "9876543210";
// Calling printNum function to
// print array word by word.
printNum(num);
return 0;
}
void printNum(char *num){
/**********************************************
This function takes a pointer to an array and
call itself again and again untill it founds
null character
***********************************************/
char *pnum;
pnum = num;
printf("%c\n", *pnum); // print character on current address
if(*pnum!='\0') // This logic is used to avoid any loop
printNum(++pnum); // increment 1 byte to address and call the funtion.
}

Creating a function which removes an input digit from a bigger number in c

I'm trying to write a function in c with little success.
The function needs to be recursive and accepts 2 ints - a natural number and a single digit in C
The function removes the the input digit from the natural number without shifting it's order.
For example:
if my digit is = 5 and my number is = 512556915
the function will return the number = 12691 , removing all the 5's from it without changing the other digits' order.
Any help would be appreciated.
You can try to convert your int into char* with the itoa() function, remove it all of the '5' digits, and re-convert it into an int with the atoi() function.
If you want recursive function, find the example below.
Which calls the function recursively until number becomes 0 and adds up the reminder.
int removeNum(int num, int digit)
{
if (num == 0) return 0;
int result = removeNum(num/10,digit);
if (num%10 != digit)
result = 10*result + (num%10);
return result;
}

How to extract last 3 digit of an array of a string and store it to different int array in C

I want to extract last 3 digit of a string suppose like :
char a[100][100] = ["17BIT0111" , "17BIT0222", ... n];
and I want to take last three digits and store in different array like
int b[100] =[111 , 222 , ... n];
I took reference from this but I wan't it without using pointer or a linked list. As I am gonna use it for comparing stack.
C program to extract different substrings from array of strings
Something like this:
for (int i = 0; i < 100; ++i)
{
unsigned int value = 0;
sscanf(a[i], "17BIT%u", &value);
b[i] = (int) (value % 1000);
}
This doesn't check the return value of sscanf(), instead defaulting the value to 0 in case conversion fails.
This will convert a larger integer, so the % 1000 was added to make sure only the last three digits really matter in the conversion. The unsigned is simply to disallow embedded dashes in the string, which makes sense to me in cases like these.

Translate string to number

I am looking for a way to take a string and check 3 possibilities.
Digit and thus converts it to a signed int (not a long)
Is a symbolic representation previously defined at runtime, and converts it to a signed int
Neither
The "symbolic representation" will be basically like an associative array that starts at 0 elements and expands as more symbols are added. For example lets say for instance that C had associative arrays (I wish) with this peusdocode:
symbol_array['q'] = 3;
symbol_array['five'] = 5;
symbol_array['negfive'] = -5;
symbol_array['random294'] = 28;
signed int i;
string = get_from_input();
if(!(i = convert_to_int(string))) {
if(!(i = translate_from_symbol(string))) {
printf("Invalid symbol or integer\n");
exit(1);
}
}
printf("Your number: %d\n, i);
The idea being if they entered "5" it would convert it to 5 via convert_to_int, and if they entered "five" it would convert it to 5 via translate_from_symbol. As what I feel may be hardest is if they entered "random294" it wouldn't convert it to 294, but to 28. If they entered "foo" then it would exit(1).
My general questions are these: (Instead of making multiple posts)
When making convert_to_int I know I shouldn't use atoi because it doesn't fail right. Some people say to use strtol but it seems tedious to convert it back to a non-long int. The simplistic (read: shortest) way I've found is using sscanf:
int i;
if ((sscanf(string, "%d", &i)) == 1){
return i;
}
However, some people look down on that even. What is a better method if not sscanf or converting strtol?
Secondly, how can I not only return an integer but also know if it found one. For example if the user entered "0" then it would return 0, thus setting off my FALSE in my if statement. I had considered using -1 if not found but since I am returning signed int's then this also suffers from the same problem. In PHP I know for example with strpos they use === FALSE
Finally, is there any short code that emulates associate arrays and/or lets me push elements on to the array in runtime?
First, you might want to revise your syntax and set the keyword apart from the operand, i.e. "neg five" instead of "negfive". Otherwise your symbol lookup for the keywords has to consider every prefix. ("random294" might be okay if your keywords aren't allowed to have digits in them.)
Sure, sscanf tells you whether you found a decimal in the return value and writes that decimal to a separate int, which is nice, but you'll have to watch out for trailing characters by checking that the number of characters read equals the length of your string with the %n format. Otherwise, sscanf will consider 5x as legal decimal number. strtol also returns a pointer to the location after the parsed decimal number, but it relies too much on checking err for my taste.
The fact that strtol uses long integers shouldn't be an issue. If the input doesn't fit into an int, return INT_MAX or INT_MIN or issue an error.
You can also easily write a wrapper function around sscanf or strtol that suits your needs better. (I know I'd like a function that returns true on success and stores the integer via a pointer argument, sscanf style, where success means: no trailing non-digit characters.)
Finally, about the associative arrays: There is no short code, at least not in C. You'll have to implement your own hash map or use a library. As a first draft, I'd use a linear list of strings and check them one by one. This is a very naive approach, but easy to implement. I assume that you don't start out with a lot of symbols, and you're not doing a lot of checks, so speed shouldn't be an issue. (You can sort the array and use binary search to speed it up, but you'd have to re-sort after every insertion.) Once you have the logic of your program working, you can start thinking about hash maps.
Something like this should do your job:
#include <stdio.h>
#include <string.h>
struct StringToLongLookUp {
char *str;
char *num;
};
struct StringToLongLookUp table[] =
{
{ "q" , "3" },
{ "five" , "5" },
{ "negfive" , "-5" },
{ "random294", "28" }
};
int translate_from_symbol(char **str)
{
int i;
for(i = 0; i < (sizeof(table) / sizeof(struct StringToLongLookUp)); i++)
{
if(strcmp(*str, table[i].str) == 0)
{
*str = table[i].num;
return 1; // TRUE
}
}
return 0; // FALSE
}
int main()
{
char buf[100];
char *in = buf;
char *out;
int val;
scanf("%s", in);
translate_from_symbol(&in);
val = strtol(in, &out, 10);
if (in != out)
{
printf("\nValue = %d\n", val);
}
else
{
printf("\nValue Invalid\n");
}
}
Of course, you get a long, but converting that to int shouldn't be an issue as mentioned above.

Resources