Convert a string to an integral number? - c

How is this even possible? One of my textbook questions (studying for an exam here) claim you can do this and ask the following:
Write a function that accepts a string. The function should convert the string to an integral number. If it cannot convert return 0.
Example 1: 8976 returns the value of
((((8*10 + 9) *10)+ 7 )* 10) + 6
Example 2: 67A returns a value of 0
How can this be done? I know you can use the atoi() function but the book wants this to be done without any functions?
Edit: Some further thinking:
int i, ans;
char number[5]="8976";
for(i=0;i<strlen(number);i++)
ans=(ans*10)+(number[i]-'0');
Would the above work?

I was writing something but in the meantime the question was basically answered, in the OP edits and further comments.
Here is the function header:
int f(const char *str)
{
The variables: v is the computed value, c is a pointer to the current character being scanned, d is the value of the current digit.
int v;
const char *c;
int d;
v = 0;
c = str;
Iteration will stop on the null terminator, when c points to 0, which is FALSE in C. Scanning is left to right.
while (*c)
{
The OP got the main idea right.
v *= 10;
d = *c - '0';
You should just test d to check that it is between 0 and 9.
if (d < 0 || d > 9)
return 0;
This solution uses pointers in place of indices.
v += d;
++c;
}
Return the result.
return v;
}

You're halfway there, your code isn't bad just missing a declaration and an if
int main()
{
int i, ans;
ans=0;
char number[5]="12";
for(i=0;i<strlen(number);i++){
if( !(number[i]>='0' && number[i]<='9') ){
ans = 0;
break;
}
ans=(ans*10)+(number[i]-'0');
}
printf("%d\n",ans);
return 0;
}
you can also check the code here:
http://cfiddle.net/cvYCYB

Related

Ex. 2.1 K&R 2nd edition: How can I calculate the variables?

I am a beginner in programming. I referred to power function in chapter 1 and modified it to be power_sum function. My calculation is to insert value of bits in "show_val()" to show range of each variable. The problem is in the main when I want to insert a value into show_val. Please guide me how to solve this. Thank you.
#include <stdio.h>
int power_sum(int base, int n);
void show_val(int power);
int main() {
unsigned char vc = show_val(8);
/* I try to show range of unsigned char here, but because show_val
is a void function, so it becomes error.*/
}
/* power_sum: raise base to n-th power and sum up; n => 0 */
int power_sum(int base, int n) {
int i, p, sum;
p = 1;
sum = 0;
for (i = 1; i <= n; ++i) {
p = p * base;
sum = sum + p;
}
sum = sum - 2;
return sum;
}
/* show_val: to show value of each variable */
void show_val(int pw) {
int n;
int i;
n = power_sum(2, pw);
for (i = 0; i < 10; ++i) /* to display increments of a value ten times */ {
printf("%d\n", ++n);
}
}
You are trying to assign void function void show_val(int pw) (a function that returns nothing) to unsigned char vc variable. If you want to return value from show_val function change: int show_val(int pw) and return something.
Otherwise, if you don't want to return anything, you can just call function in main:
int main()
{
show_val(8);
}
unsigned char vc = show_val(8);
Let us break the above piece of code into LHS and RHS.
LHS :
Its a variable expecting a character to be inputed.
Now what is being done in RHS
RHS:
You have given show_val(8)
Which is a mistake
Why?
Because if you see you show_val declaration:
void show_val(int)
You are returning a void i.e nothing.
And trying to equate with char on LHS.
So, the compiler will definitely throw an error.
There are more changes to be made,
1st edit this part correctly in the question if you are clear and then we can look upon the other changes.

While trying to write the recursive version of atoi, what is the meaning of itoa(n /10, s) and why is it advisable to avoid static int i = 0?

I'm sorry if my question is quite vague, because it is without context. So I was trying to solve a question: Write a recursive version of the function itoa(i) which converts an integer i into a string.
As I ran out of idea how to solve it, I started looking online to find solutions and I came across some of them which usually use this line: itoa(n/10, s);. For example, from this StackOverflow question: itoa recursively. I can't understand what it does to i.
So I went on and searched for more solutions and I found one that actually works, the program looks like this:
#include <stdio.h>
char *itoa(int n, char s[]);
int main()
{
char number[100];
printf("-90 to string = %s\n", itoa(-90, number));
return 0;
}
char *itoa(int n, char s[])
{
static int i = 0;
if (n < 0) {
s[i++] = '-';
n = -n; /* does not work for largest negative number in two complement */
}
if (n / 10)
itoa(n /10, s);
s[i++] = n % 10 + '0';
s[i] = '\0';
return s;
}
Problem is, according to the solutions I found on other websites, people said that we should avoid using static int i. I did not read why we should do so because I don't know how static works so I don't know if this program is fine or needs improvements.
Your function pretty much almost right, that is for a recursive method. If you were going to parse the digit to string backward, it is right. Otherwise, I just did a couple fix.
For parsing digit to string, the digits that are being parsed are from the right digits to left digits as the remainder is what being used. Thus, when storing those into a string, we will need to go from high to low indexes. If we use remainders for parsing, we will not know the length of the number that is being parsed. Thus, in most parse cases there will be some extra spaces at the beginning of your string or char array.
For using the static i, you can pass a version of it around but it would make it harder to use as you would need to know to always have to pass i at 11. "i" is at 11 because the maximum digits for an int is 10(digits) + 1 sign and the 12th character which not counted by "i" is the null char. To make it easier to use the function, I configured the third parameter to be a void pointer. However, do not pass it an actual pointer, pass it a NULL. When it see NULL as the third parameter, it know that, that is the first call.
#include <stdio.h>
#include <string.h>
char *itoa(int n, char s[], void * );
int main()
{
char number[100] = {0};
printf("-90 to string = %s\n", itoa(154, number, NULL));
printf("-15 to string = %s\n", itoa(-15, number, NULL));
printf("-2147483648 to string = %s\n", itoa(-2147483648, number, NULL));
return 0;
}
// The reason why I pass a void pointer is because
// instead of passing the value is because it easier to use function without needing to know that the string have to go from right left.
// When you first call it just use NULL as the third parameter. Anything else can ruin it.
char *itoa(int n, char s[], void * firstCall )
{
static int i;
if ( firstCall == NULL ) {
i = 11;
s[11] = 0;
}
int neg = 0;
if (n < 0) {
if ( n == -2147483648 ) {
strcpy(s, "-2147483648");
return s;
}
neg=1;
n = -n; /* does not work for largest negative number in two complement */
}
s[--i] = (n % 10) ^ 48;
if ( n / 10 ) itoa(n / 10, s, s);
if ( neg == 1 ) s[--i] = '-';
return &s[i];
}

How to convert a string to double floating-point value?

sorry if the title is confusing, I just need some experienced programmers to attempt to clarify something for me. So one of my homework questions asks me this (the language is c):
Write a function that receives a string and returns a double floating-point value. The fucntion declaration would look like this
double convertFloat(char s[]);
Do not use the strtol() function or any other standard c library function. Write your own!... Note that the input string could have any of the following sample formats: "1.34", "-1.4554", "6".
I am just not sure how to approach this because I am not sure what is being asked here. If I had to write a function to find a square root or something like that I could do it no problem but it seems that I have to take strings that are all numbers and convert them to floats... just not sure where to start and googling similar things has yielded no results.
Thank you all in advance.
- Davey
Start by writing
unsigned int convertUnsignedInt(const char *s);
// e.g. convertUnsignedInt("42") == 42
It's a bit simpler because you don't have to handle negative numbers or fractions, but it shows the general principle.
Here is the complete code to your problem. The code is understandable. Ask if you have any doubts regarding it.
#include <stdio.h>
int power(int n, int m)
{
if (m == 1)
return n;
else
return n * (power(n, m - 1));
}
int getLength(char s[])
{
int i = 0;
for(i = 0; s[i] != '\0'; i++);
return i;
}
double convertFloat(char s[])
{
int len = getLength(s);
int dotpos = 0;
double result = 0.0f;
int n = 0, flag = 0;
if(s[0] == '-')
{
n = 1;
flag = 1;
}
for (; n < len; n++)
{
if (s[n] == '.')
{
dotpos = len - n - 1;
}
else
{
result = result * 10 + (s[n] - '0');
}
}
result /= power(10, dotpos);
if(flag)
return result*-1;
return result;
}
int main()
{
char str[] = "126433.47";
printf("%f", convertFloat(str));
}

C conver unsigned char to HEX

is convert unsigned char / int to hex, trouble is no correct translate ascci table:
original: 0D, converted: AD
code:
char int_to_hex(int d) {
if (d < 0) return -1;
if (d > 16) return -1;
if (d <= 9) return '0' + d;
d -= 10;
return (char)('A' + d);
}
void uint_to_hex(unsigned char in, char **out, int *olen) {
int i = 0;
int remain[2];
int result = (int)in;
while (result) {
remain[i++] = result % 16;
result /= (int)16;
}
for (i = 1; i >= 0; --i) {
char c = int_to_hex(remain[i]);
if( (int)c == -1 ) { continue; }
*((*out) + (*olen)) = (char)c; (*olen)++;
}
}
where is incorrect ?..
First of all one hex digit will cover values from 0 (0) to 15 (F) not from 0 to 16 (as you seem to assume in int_to_hex function).
Also you don't really need typecasting to char in last return of that function.
In fact all typecasts here are rather unnecessary
And typecasting of literal 16 is purely absurd...
And how sample input for uint_to_hex is looking ? You are aware, that on input (in) you can pass only single character ?
I think that char pointer would suffice for out - i mean, you want to return array, right ?
So instead of ** should be only singe *.
And I don't understand why olen has to be pointer (and argument to function too).
And you should try to write more concise and readable code, it will help you understand what you are doing too.

Convert string to integer recursively?

Here is a simple function that converts a string to an integer.
int str2int(char *str)
{
int ret = 0;
char *c;
for (c = str; (*c != '\0') && isdigit(*c); ++c)
ret = ret*10 + *c - '0';
return ret;
}
As an exercise, I'd like to write a recursive function that does the same thing. This is what I came up with.
int str2int2(char *c, int *i)
{
if (*c == '\0' || !isdigit(*c))
return *i;
*i = *i * 10 + *c - '0';
return str2int2(c + 1, i);
}
.
.
int i = 0;
.
... str2int2(str, &i);
Is there a way to write the recursive function without using the extra int* argument?
Sure, it's easy enough, but you need to write two functions, one with an accumulator, like this:
int str2int_rec(char *c, int accum)
{
if (!c || !*c || !isdigit(*c))
return accum;
return str2int_rec(c + 1, accum * 10 + (*c - '0'));
}
int str2int(char *c)
{
return str2int_rec(c, 0);
}
Well, you could hide the functionality from the person using the function. So you will have a function named int str2int(char *str) which will call int str2int(char *c, int *i) thereafter.
It's how I've done it in the past.
I think you may use horner scheme in order not to keep any 'i'.
You must reverse the string (yeah quit ugly) and then you can simply use:
int str2int (char* str)
{
if (*str+1)
{
return 10*str2int(str+1)+(*str-'0');
}
return 0;
}
One way could involve passing the length of the digit as an argument so we can read backwards efficiently:
int strtoi(char *c, size_t l)
{
return l ? c[l-1] - '0' + 10 * strtoi(c, l - 1) : 0;
}
Then call it like this:
int i = strtoi("432", 3);
Or:
char *c = "432";
int i = strtoi(c, strlen(c));
But it's not always optimal to bother with the length of a string. Plus, if a string has characters after a number, we'd have to factor that in manually, because this function won't do it for us. We can't (shouldn't) use strlen() inside our function to avoid having to pass arguments, because that can cause a considerable slowdown to recalculate the string's length every time. Surely there must be a way to do this from the beginning, even if we have to bring out the heavy artillery:
int strtoi(char *c)
{
if(!isdigit(*c)) return 0;
int i = strtoi(c + 1);
return i + pow(10, (int)(log(i + 1)/log(10)) + (i != 0)) * (*c - '0');
}
And no, that (int) cast isn't optional. Basically, all of that math calculates the power of 10 we need to multiply our current digit by, based on the number returned by the last recursive call.
I understand this is probably a learning exercise, but recursion is not the be-all, end-all of programming. In some languages, and for some tasks, it is what some, myself included, would call beautiful, but from the looks of it this is not one of those cases.

Resources