Base conversion using recursion - c

I'm working on an assignment and have it partially solved.
Currently I'm getting the correct output, only in reverse.
Here's the helper function I've implemented:
char int2char (int radix, int value) {
char c = '?';
if ((value >= 0 && value < radix) && (radix <= 36 && radix >= 2)){
if (value < 10){
c = value + 48;
}
else if (value >= 10 && value < 36) {
c = value + 55;
}
}
return c;
}
And the actual function I'm having difficulty with looks like this thus far:
void int2str (int radix, int value) {
int result = value % radix;
int division = value / radix;
char c;
c = int2char(radix, result);
putchar(c);
while (division > 0) {
return int2str(radix, division);
}
}
The first function is used to represent the digits 10-35 in hex. So if the modulus produces an 11, for example, I'm supposed to output a 'B'.
This is working great, except backwards! And I can't figure out how to reverse it. The biggest hitch is you can only use putchar() as an output. No strings, no arrays.
To further clarify, if I enter:
int2str 16 60
The output should be '3C', instead I'm getting 'C3'.

First off, your use of while is confusing, since there's a return in it. Replace that with if. The return is unnecessary, since the function will return on its own at the end.
Once you've done that, you can reverse the output by moving the putchar after the recursive call:
if (division > 0) {
int2str(radix, division);
}
putchar(c);
As a side note, return int2str(radix, division); doesn't make sense in this function anyway, since it's a void function, so there's nothing to return. If you did want to do this (you don't in this case), you would say:
somefunction();
return;
Also, this may be more clear if you used '0' and 'A' instead of 48 and 55:
if (value < 10){
c = value + '0';
}
else if (value >= 10 && value < 36) {
c = value - 10 + 'A';
}

result is the last digit, but you're printing it first. Drop the return from the recursive call and move the putchar to the end. Also, the while loop should be an if.
void int2str(int radix, int value) {
int lastdigit = value % radix;
int firstdigits = value / radix;
if (firstdigits) {
int2str(radix, firstdigits);
}
putchar(int2char(radix, lastdigit));
}

Try this
c = int2char(radix, result);
if (division > 0)
int2str(radix, division);
putchar(c);
Last call to int2str will print first digit while first call will print last digit.

Related

how to know the difference between the sum of the values of the even index and the sum of the values of the odd index in an array (recursive code)

(recursive solutions only ) I'm using the function : int diff(char str[],int i)
the input is the string : 123, the sum of the values in the even indexes is 1+3=4
the sum of the values in the odd indexes is 2
so the difference between the sum of the values of the even index and the sum of the values of the odd index in an array is :4-2= 2.
I have written this in the main but its not right ,how can I fix my code ??? :
printf("Enter a string:");
if(scanf("%s",str)!=1)
{
printf("Input error");
return 1;
}
printf("The difference is: %d", diff(str, 0));
return 0;
and outside the main was the function :
int diff (char str[], int i)
{
if(str[i]=='\0' || i>=100)
return 0;
if(i%2==0)
return (str[i]+diff(str,i+1));
else
return (-str[i] +diff(str,i+1));
}
Another approach could be:
int diff (const char str[])
{
if (str[0] == '\0')
return 0;
if (str[1] == '\0')
return str[0] - '0';
return str[0] - str[1] + diff(str + 2);
}
The code, as written, is not working because it is not converting the character codes held in str to integer values in the range 0-9.
If the input to the diff function was "12345" then inspection of the values of str[0], str[1], ... str[5] either with the debugger or printing them out would show them to be (assuming an ASCII-derived encoding):
49 50 51 52 53
Luckily, (and thanks to user #SomeProgrammerDude for pointing this out), the C standard requires (see, for example: ISO/IEC 9899:TC3 §5.2.1, paragraph 3):
In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.
What this means in practice is you can convert the characters '0','1',...,'9' to their equivalent values by subtracting '0'.
int value = str[i] - '0';
Adding this to code gives a working version of diff:
int diff (char str[], int i)
{
if(str[i]=='\0' || i>=100)
return 0;
int value = str[i] - '0';
if(i%2 == 0)
return (value + diff(str, i+1));
else
return (-value + diff(str, i+1));
}

How do I check the first two characters of my char array in C?

This is code to create a similar C library function atoi() without the use of any C runtime library routines.
I'm currently stuck on how to check for the first two digits of the char array s to see whether the input begins with "0x".
If it starts with 0x, this means that I can then convert it in to hexadecimal.
#include <stdio.h>
int checkforint(char x){
if (x>='0' && x<='9'){
return 1;
}
else{
return 0;
}
}
unsigned char converthex(char x){
//lets convert the character to lowercase, in the event its in uppercase
x = tolower(x);
if (x >= '0' && x<= '9') {
return ( x -'0');
}
if (x>='a' && x<='f'){
return (x - 'a' +10);
}
return 16;
}
int checkforhex(const char *a, const char *b){
if(a = '0' && b = 'x'){
return 1;
}else{
return 0;
}
}
//int checkforint
/* We read an ASCII character s and return the integer it represents*/
int atoi_ex(const char*s, int ishex)
{
int result = 0; //this is the result
int sign = 1; //this variable is to help us deal with negative numbers
//we initialise the sign as 1, as we will assume the input is positive, and change the sign accordingly if not
int i = 0; //iterative variable for the loop
int j = 2;
//we check if the input is a negative number
if (s[0] == '-') { //if the first digit is a negative symbol
sign = -1; //we set the sign as negative
i++; //also increment i, so that we can skip past the sign when we start the for loop
}
//now we can check whether the first characters start with 0x
if (ishex==1){
for (j=2; s[j]!='\0'; ++j)
result = result + converthex(s[j]);
return sign*result;
}
//iterate through all the characters
//we start from the first character of the input and then iterate through the whole input string
//for every iteration, we update the result accordingly
for (; s[i]!='\0'; ++i){
//this checks whether the current character is an integer or not
//if it is not an integer, we skip past it and go to the top of the loop and move to the next character
if (checkforint(s[i]) == 0){
continue;
} else {
result = result * 10 + s[i] -'0';
}
//result = s[i];
}
return sign * result;
}
int main(int argc)
{
int isithex;
char s[] = "-1";
char a = s[1];
char b = s[2];
isithex=checkforhex(a,b);
int val = atoi_ex(s,isithex);
printf("%d\n", val);
return 0;
}
There are several errors in your code. First, in C you start counting from zero. So in main(), you should write:
char a = s[0];
char b = s[1];
isithex = checkforhex(a, b);
Then, in checkforhex(), you should use == (two equal signs) to do comparisons, not =. So:
if (a == '0' && b == 'x')
However, as pointed out by kaylum, why not write the function to pass a pointer to the string instead of two characters? Like so:
int checkforhex(const char *str) {
if (str[0] == '0' && str[1] == 'x') {
...
}
}
And in main() call it like so:
isithex = checkforhex(s);

How to convert a char* to a number function with a comma (decimal point)?

I wrote change() to help me convert a string to a double.
For example: if the string is "5.5", I want the number to be 5.5. If the string is "0.0", I want the number to be 0. Another example: "50" to 50.
Now the problem is when I use the change() with pow() that is in the library math.h, everything works perfectly fine and I tested it with a lot of inputs and all worked perfect.
Example to a test :
change("5.0") gives me 5
change("1.5") gives me 1.5
Since I can't use the library math I wrote power(), but when I test change(), now I don't get an output. I think it is stuck in an infinite loop.
Any help why this thing is happening?
double change(char* Point) {
int count = 0;
double res = 0;
while (*Point == '0') {
Point++;
}
while (*Point != '.' && *Point) {
count++;
Point++;
}
int num1 = 0;
for (int i = 0; i < count; i++) {
Point--;
num1 = (*Point - '0') * (power(10, i));
}
int i = -1;
while (*Point != '.' && *Point) {
Point++;
}
double num2 = 0;
if (!*Point) {
return res = (double) num1 + num2;
}
Point++;
while (*Point) {
num2 = (double) (*Point - '0') * (double) (power(10, i));
i--;
Point++;
}
res = (double) num1 + num2;
return res;
}
I also wrote the function power:
int power(int base,int exp)
{
int result=1;
if(exp == 0){
return 1;
}
while (exp != 0)
{
result=result*base;
exp--;
}
return result;
}
Because you call the function power(10,i) in the change function, while i have a negative value. You can fix this by adding an if statement in your power function
if (exp < 0) {
exp = 0 - exp;
return(1/power(base,exp));
}
Edit : you also have to change the power function to return double instead of int
you can convert a string to a float using atof()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
float val;
char str[20];
strcpy(str, "98993489");
val = atof(str);
printf("String value = %s, Float value = %f\n", str, val);
return(0);
source of code : https://www.tutorialspoint.com/c_standard_library/c_function_atof.htm
As already established, the problem is this loop will never end if exp is less than 0 in your power function.
while (exp != 0)
{
result=result*base;
exp--;
}
But your code still won't work if you fix this because you're only ever storing one digit in num1
num1 = (*Point - '0') * (power(10, i));
If you pass in, for example, "50" it'll work fine and you'll get 50 back, but if you pass in "54" you'll also get 50 as you lose the 4.
You need to add the newly calculated digit to the existing value like so.
num1 += (*Point - '0') * (power(10, i));
You can greatly simplify that first bit of the function and remove the need to use power though by realising that as you move through the string, you can just multiple the current value of num1 by 10 and then add on the new digit. This means you only process the string before the decimal point just once rather than 3 times.
int num1 = 0;
for(;isdigit(*Point);Point++) {
num1 *= 10;
num1 += *Point - '0';
}
I've also replaced *Point != '.' && *Point with isdigit(*Point) (from "ctype.h") as that ensures that if it encounters something that isn't a number character, it doesn't try turning it into a number - you should stop processing completely at that point.
You could remove the need for power completely by using the same idea for calculating num2 as well since the amount you're dividing *Point - '0' also increases by 10 each time.

Recursive function to convert string to integer in C

I have the following working code; it accepts a string input as the function parameter and spits out the same string converted to a decimal.
I'm not going to bother accounting for negative inputs, although I understand that I can set a boolean flag to true when the first indexed character is a "-". If the flag switches to true, take the total output and multiply by -1.
Anyway, I'm pretty stuck on where to go from here; I'd like to adjust my code so that I can account for a decimal place. Multiplying by 10 and adding the next digit (after converting that digit from an ASCII value) yields an integer that is displayed in decimal in the output. This obviously won't work for numbers that are smaller than 1. I understand why (but not really how) to identify where the decimal point is and say that "for anything AFTER this string index containing a decimal point, do this differently"). Also, I know that instead of multiplying by a power of 10 and adding the next number, I have to multiply by a factor of -10, but I'm not sure how this fits into my existing code...
#include <stdio.h>
#include <string.h>
int num = 0;
int finalValue(char *string1) {
int i = 0;
if (string1[i] != '\0') {
if (string1[i]<'0' || string1[i]>'9') {
printf("Sorry, we can't convert this to an integer\n\n");
}
else {
num *= 10;
num += string1[i] - '0';
//don't bother using a 'for' loop because recursion is already sort-of a for loop
finalValue(&string1[i+1]);
}
}
return num;
}
int main(int argc, const char * argv[]) {
printf("string to integer conversion yields %i\n",(finalValue("99256")));
return 0;
}
I made some adjustments to the above code and it works, but it's a little ugly when it comes to the decimal part. For some reason, the actual integer output is always higher than the string put in...the math is wrong somewhere. I accounted for that by subtracting a static amount (and manually multiplying by another negative power of 10) from the final return value...I'd like to avoid doing that, so can anybody see where my math / control flow is going wrong?
#include <stdio.h>
#include <string.h>
//here we are setting up a boolean flag and two variables
#define TRUE 1
#define FALSE 0
double num = 0;
double dec = 0.0;
int flag = 0;
double final = 0.0;
double pow(double x, double y);
//we declare our function that will output a DOUBLE
double finalValue(char *string1) {
//we have a variable final that we will return, which is just a combination of the >1 and <1 parts of the float.
//i and j are counters
int i = 0;
int j = 0;
//this will go through the string until it comes across the null value at the very end of the string, which is always present in C.
if (string1[i] != '\0') {
//as long as the current value of i isn't 'null', this code will run. It tests to see if a flag is true. If it isn't true, skip this and keep going. Once the flag is set to TRUE in the else statement below, this code will continue to run so that we can properly convert the decimal characers to floats.
if (flag == TRUE) {
dec += ((string1[i] - '0') * pow(10,-j));
j++;
finalValue(&string1[i+1]);
}
//this will be the first code to execute. It converts the characters to the left of the decimal (greater than 1) to an integer. Then it adds it to the 'num' global variable.
else {
num *= 10;
num += string1[i] - '0';
// This else statement will continue to run until it comes across a decimal point. The code below has been written to detect the decimal point and change the boolean flag to TRUE when it finds it. This is so that we can isolate the right part of the decimal and treat it differently (mathematically speaking). The ASCII value of a '.' is 46.
//Once the flag has been set to true, this else statement will no longer execute. The control flow will return to the top of the function, and the if statement saying "if the flag is TRUE, execute this' will be the only code to run.
if (string1[i+1] == '.'){
flag = TRUE;
}
//while this code block is running (before the flag is set to true) use recursion to keep converting characters into integers
finalValue(&string1[i+1]);
}
}
else {
final = num + dec;
return final;
}
return final;
}
int main(int argc, const char * argv[]) {
printf("string to integer conversion yields %.2f\n",(finalValue("234.89")));
return 0;
}
I see that you have implemented it correctly using global variables. This works, but here is an idea on how to avoid global variables.
A pretty standard practice is adding parameters to your recursive function:
double finalValue_recursive(char *string, int flag1, int data2)
{
...
}
Then you wrap your recursive function with additional parameters into another function:
double finalValue(char *string)
{
return finalValue_recursive(string, 0, 0);
}
Using this template for code, you can implement it this way (it appears that only one additional parameter is needed):
double finalValue_recursive(char *s, int pow10)
{
if (*s == '\0') // end of line
{
return 0;
}
else if (*s == '-') // leading minus sign; I assume pow10 is 0 here
{
return -finalValue_recursive(s + 1, 0);
}
else if (*s == '.')
{
return finalValue_recursive(s + 1, -1);
}
else if (pow10 == 0) // decoding the integer part
{
int digit = *s - '0';
return finalValue_recursive(s + 1, 0) * 10 + digit;
}
else // decoding the fractional part
{
int digit = *s - '0';
return finalValue_recursive(s + 1, pow10 - 1) + digit * pow(10.0, pow10);
}
}
double finalValue(char *string)
{
return finalValue_recursive(string, 0);
}
Also keep track of the occurrence of the decimal point.
int num = 0;
const char *dp = NULL;
int dp_offset = 0;
int finalValue(const char *string1) {
int i = 0;
if (string1[i] != '\0') {
if (string1[i]<'0' || string1[i]>'9') {
if (dp == NULL && string1[i] == '.') {
dp = string1;
finalValue(&string1[i+1]);
} else {
printf("Sorry, we can't convert this to an integer\n\n");
} else {
} else {
num *= 10;
num += string1[i] - '0';
finalValue(&string1[i+1]);
}
} else if (dp) {
dp_offset = string1 - dp;
}
return num;
}
After calling finalValue() code can use the value of dp_offset to adjust the return value. Since this effort may be the beginning of a of a complete floating-point conversion, the value of dp_offset can be added to the exponent before begin applied to the significand.
Consider simplification
//int i = 0;
//if (string1[i] ...
if (*string1 ...
Note: using recursion here to find to do string to int is a questionable approach especially as it uses global variables to get the job done. A simply function would suffice. Something like untested code:
#include <stdio.h>
#include <stdlib.h>
long long fp_parse(const char *s, int *dp_offset) {
int dp = '.';
const char *dp_ptr = NULL;
long long sum = 0;
for (;;) {
if (*s >= '0' && *s <= '9') {
sum = sum * 10 + *s - '0';
} else if (*s == dp) {
dp_ptr = s;
} else if (*s) {
perror("Unexpected character");
break;
} else {
break;
}
s++;
}
*dp_offset = dp_ptr ? (s - dp_ptr -1) : 0;
return sum;
}
Figured it out:
#include <stdio.h>
#include <string.h>
//here we are setting up a boolean flag and two variables
#define TRUE 1
#define FALSE 0
double num = 0;
double dec = 0.0;
int flag = 0;
double final = 0.0;
double pow(double x, double y);
int j = 1;
//we declare our function that will output a DOUBLE
double finalValue(char *string1) {
//i is a counter
int i = 0;
//this will go through the string until it comes across the null value at the very end of the string, which is always present in C.
if (string1[i] != '\0') {
double newGuy = string1[i] - 48;
//as long as the current value of i isn't 'null', this code will run. It tests to see if a flag is true. If it isn't true, skip this and keep going. Once the flag is set to TRUE in the else statement below, this code will continue to run so that we can properly convert the decimal characers to floats.
if (flag == TRUE) {
newGuy = newGuy * pow(10,(j)*-1);
dec += newGuy;
j++;
finalValue(&string1[i+1]);
}
//this will be the first code to execute. It converts the characters to the left of the decimal (greater than 1) to an integer. Then it adds it to the 'num' global variable.
else {
num *= 10;
num += string1[i] - '0';
// This else statement will continue to run until it comes across a decimal point. The code below has been written to detect the decimal point and change the boolean flag to TRUE when it finds it. This is so that we can isolate the right part of the decimal and treat it differently (mathematically speaking). The ASCII value of a '.' is 46.
//Once the flag has been set to true, this else statement will no longer execute. The control flow will return to the top of the function, and the if statement saying "if the flag is TRUE, execute this' will be the only code to run.
if (string1[i+1] == 46){
flag = TRUE;
finalValue(&string1[i+2]);
}
//while this code block is running (before the flag is set to true) use recursion to keep converting characters into integers
finalValue(&string1[i+1]);
}
}
else {
final = num + dec;
return final;
}
return final;
}
int main(int argc, const char * argv[]) {
printf("string to integer conversion yields %.2f\n",(finalValue("234.89")));
return 0;
}

Questions about a Kernighan and Ritchie Excercise 2-3

I'm trying to write a program in C that converts hexadecimal numbers to integers. I've written successfully a program that converts octals to integers. However, the problems begin once I start using the letters (a-f). My idea for the program is ads follows:
The parameter must be a string that starts with 0x or 0X.
The parameter hexadecimal number is stored in a char string s[].
The integer n is initialized to 0 and then converted as per the rules.
My code is as follows (I've only read up to p37 of K & R so don't know much about pointers) :
/*Write a function htoi(s), which converts a string of hexadecimal digits (including an optional 0x or 0X) into its equivalent integer value. The allowable digits are 0 through 9, a through f, and A through F.*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
int htoi(const char s[]) { //why do I need this to be constant??
int i;
int n = 0;
int l = strlen(s);
while (s[i] != '\0') {
if ((s[0] == '0' && s[1] == 'X') || (s[0] == '0' && s[1] == 'x')) {
for (i = 2; i < (l - 1); ++i) {
if (isdigit(s[i])) {
n += (s[i] - '0') * pow(16, l - i - 1);
} else if ((s[i] == 'a') || (s[i] == 'A')) {
n += 10 * pow(16, l - i - 1);
} else if ((s[i] == 'b') || (s[i] == 'B')) {
n += 11 * pow(16, l - i - 1);
} else if ((s[i] == 'c') || (s[i] == 'C')) {
n += 12 * pow(16, l - i - 1);
} else if ((s[i] == 'd') || (s[i] == 'D')) {
n += 13 * pow(16, l - i - 1);
} else if ((s[i] == 'e') || (s[i] == 'E')) {
n += 14 * pow(16, l - i - 1);
} else if ((s[i] == 'f') || (s[i] == 'F')) {
n += 15 * pow(16, l - i - 1);
} else {
;
}
}
}
}
return n;
}
int main(void) {
int a = htoi("0x66");
printf("%d\n", a);
int b = htoi("0x5A55");
printf("%d\n", b);
int c = htoi("0x1CA");
printf("%d\n", c);
int d = htoi("0x1ca");
printf("%d\n", d);
}
My questions are:
1. If I don't use const in the argument for htoi(s), i get the following warnings from the g++ compiler :
2-3.c: In function ‘int main()’: 2-3.c:93:20: warning: deprecated
conversion from string constant to ‘char*’ [-Wwrite-strings]
2-3.c:97:22: warning: deprecated conversion from string constant to
‘char*’ [-Wwrite-strings] 2-3.c:101:21: warning: deprecated conversion
from string constant to ‘char*’ [-Wwrite-strings] 2-3.c:105:21:
warning: deprecated conversion from string constant to ‘char*’
[-Wwrite-strings]
Why is this?
2.Why is my program taking so much time to run? I haven't seen the results yet.
3.Why is it that when I type in cc 2-3.c instead of g++ 2-3.c in the terminal, I get the following error message:
"undefined reference to `pow'"
on every line that I've used the power function?
4. Please do point out other errors/ potential improvements in my program.
If I don't use const in the argument for htoi(s), i get the following warnings from the g++ compiler
The const parameter should be there, because it is regarded as good and proper programming to never typecast away const from a pointer. String literals "..." should be treated as constants, so if you don't have const as parameter, the compiler thinks you are casting away the const qualifier.
Furthermore, you should declare all pointer parameters that you don't intend to modify the contents of as const, Google the term const correctness.
Why is my program taking so much time to run? I haven't seen the results yet.
I think mainly because you have made an initialization goof-up. int i; i contains rubbish. Then while (s[rubbish_value] != '\0'). This function can be written a whole lot better too. Start by checking for the 0x in the start of the string, if they aren't there, signal some error (return NULL?), otherwise discard them. Then start one single loop after that, you don't need 2 loops.
Note that the pow() function deals with float numbers, which will make your program a slight bit slower. You could consider using an integer-only version. Unfortunately there is no such function in standard C, so you will have to found one elsewhere.
Also consider the function isxdigit(), a standard function in ctype.h, which checks for digits 0-9 as well as hex letters A-F or a-f. It may however not help with performance, as you will need to perform different calculations for digits and letters.
For what it is worth, here is a snippet showing how you can convert a single char to a hexadecimal int. It is not the most optimized version possible, but it takes advantage of available standard functions, for increased readability and portability:
#include <ctype.h>
uint8_t hexchar_to_int (char ch)
{
uint8_t result;
if(isdigit(ch))
{
result = ch - '0';
}
else if (isxdigit(ch))
{
result = toupper(ch) - 'A' + 0xA;
}
else
{
// error
}
return result;
}
Don't use a C++ compiler to compile a C program. That's my first advice to you.
Secondly const in a function parameter for a char * ensures that the programmer doesn't accidentally modify the string.
Thirdly you need to include the math library with -lm as stated above.
a const char[] means that you cannot change it in the function. Casting from a const to not-const gives a warning. There is much to be said about const. Check out its Wikipedia page.
--
Probably, cc doesn't link the right libraries. Try the following build command: cc 2-3.c -lm
Improvements:
Don't use pow(), it is quite expensive in terms of processing time.
Use the same trick with the letters as you do with the numbers to get the value, instead of using fixed 'magic' numbers.
You don't need the last else part. Just leave it empty (or put an error message there, because those characters aren't allowed).
Good luck!
About my remark about the pow() call (with the use of the hexchar_to_int() function described above, this is how I'd implement this (without error checking):
const char *t = "0x12ab";
int i = 0, n = 0;
int result = 0;
for (i = 2; i < strlen(t); i++) {
n = hexchar_to_int(t[i]);
result |= n;
result <<= 4;
}
/* undo the last shift */
result >>= 4;
I just worked through this exercise myself, and I think one of the main ideas was to use the knowledge that chars can be compared as integers (they talk about this in chapter 2).
Here's my function for reference. Thought it may be useful as the book doesn't contain answers to exercises.
int htoi(char s[]) {
int i = 0;
if(s[i] == '0') {
++i;
if(s[i] == 'x' || s[i] == 'X') {
++i;
}
}
int val = 0;
while (s[i] != '\0') {
val = 16 * val;
if (s[i] >= '0' && s[i] <= '9')
val += (s[i] - '0');
else if (s[i] >= 'A' && s[i] <= 'F')
val += (s[i] - 'A') + 10;
else if (s[i] >= 'a' && s[i] <= 'f')
val += (s[i] - 'a') + 10;
else {
printf("Error: number supplied not valid hexadecimal.\n");
return -1;
}
++i;
}
return val;
}
Always init your variables int i=0, otherwise i will contain a garbage value, could be any number, not necessary 0 as you expect. You're running the while statement in an infinite loop, that's why it takes forever to get the results, print i to see why. Also, add a break if the string doesn't start with 0x, will avoid the same loop issue when the user is used on a random string. As others mention you need to import the library containing pow function and declare your string with const to get rid of the warning.
This is my version of program for the question above. It converts the string of hex into decimal digits irrespective of optional prefix(0x or 0X).
4 important library functions used are strlen(s), isdigit(c), isupper(c), isxdigit(c), pow(m,n)
Suggestions to improve the code are welcome :)
/*Program - 5d Function that converts hex(s)into dec -*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h> //Declares mathematical functions and macros
#include<string.h> //Refer appendix in Page 249 (very useful)
#define HEX_LIMIT 10
int hex_to_dec(char hex[]) //Function created by me :)
{
int dec = 0; //Initialization of decimal value
int size = strlen(hex); //To find the size of hex array
int temp = size-1 ; //Pointer pointing the right element in array
int loop_limit = 0; //To exclude '0x' or 'OX' prefix in input
if(hex[0]=='0' && ((hex[1]=='x') || (hex[1]=='X')))
loop_limit = 2;
while(temp>=loop_limit)
{
int hex_value = 0; //Temporary value to hold the equivalent hex digit in decimal
if(isdigit(hex[temp]))
hex_value = (hex[(temp)]-'0') ;
else if(isxdigit(hex[temp]))
hex_value = (toupper(hex[temp])-'A' + 10);
else{
printf("Error: No supplied is not a valid hex\n\n");
return -1;
}
dec += hex_value * pow(16,(size-temp-1)); //Computes equivalent dec from hex
temp--; //Moves the pointer to the left of the array
}
return dec;
}
int main()
{
char hex[HEX_LIMIT];
printf("Enter the hex no you want to convert: ");
scanf("%s",hex);
printf("Converted no in decimal: %d\n", hex_to_dec(hex));
return 0;
}

Resources