Reputation: 11
As a part of a larger program, I must convert a string of numbers to an integer(eventually a float). Unfortunately I am not allowed to use casting, or atoi.
I thought a simple operation along the lines of this:
void power10combiner(string deciValue){
int result;
int MaxIndex=strlen(deciValue);
for(int i=0; MaxIndex>i;i++)
{
result+=(deciValue[i] * 10**(MaxIndex-i));
}
}
would work. How do I convert a char to a int? I suppose I could use ASCII conversions, but I wouldn't be able to add chars to ints anyways(assuming that the conversion method is to have an enormous if statement that returns the different numerical value behind each ASCII number).
Upvotes: 0
Views: 188
Reputation: 2342
I would use std::stringstream, but nobody posted yet a solution using strtol, so here is one. Note, it doesn't perform handle out-of-range errors. On unix/linux you can use errno
variable to detect such errors(by comparing it to ERANGE
).
BTW, there are strtod/strtof/strtold functions for floating-point numbers.
#include <iostream>
#include <cstdlib>
#include <string>
int power10combiner(const std::string& deciValue){
const char* str = deciValue.c_str();
char* end; // the pointer to the first incorrect character if there is such
// strtol/strtoll accept the desired base as their third argument
long int res = strtol(str, &end, 10);
if (deciValue.empty() || *end != '\0') {
// handle error somehow, for example by throwing an exception
}
return res;
}
int main()
{
std::string s = "100";
std::cout << power10combiner(s) << std::endl;
}
Upvotes: 0
Reputation: 3276
There are plenty of ways to do this, and there are some optimization and corrections that can be done to your function.
1) You are not returning any value from your function, so the return type is now int.
2) You can optimize this function by passing a const reference.
Now for the examples.
Using std::stringstream to do the conversion.
int power10combiner(const string& deciValue)
{
int result;
std::stringstream ss;
ss << deciValue.c_str();
ss >> result;
return result;
}
Without using std::stringstream to do the conversion.
int power10combiner(const string& deciValue)
{
int result = 0;
for (int pos = 0; deciValue[pos] != '\0'; pos++)
result = result*10 + (deciValue[pos] - '0');
return result;
}
Upvotes: 2
Reputation: 477100
You can parse a string iteratively into an integer by simply implementing the place-value system, for any number base. Assuming your string is null-terminated and the number unsigned:
unsigned int parse(const char * s, unsigned int base)
{
unsigned int result = 0;
for ( ; *s; ++s)
{
result *= base;
result += *s - '0'; // see note
}
return result;
}
As written, this only works for number bases up to 10 using the numerals 0
, ..., 9
, which are guaranteed to be arranged in order in your execution character set. If you need larger number bases or more liberal sets of symbols, you need to replace *s - '0'
in the indicated line by a suitable lookup mechanism that determines the digit value of your input character.
Upvotes: 0
Reputation: 3968
EDITED by suggestion, and added a bit of explanation.
int base = 1;
int len = strlen(deciValue);
int result = 0;
for (int i = (len-1); i >= 0; i--) { // Loop right to left. Is this off by one? Too tired to check.
result += (int(deciValue[i] - '0') * base); // '0' means "where 0 is" in the character set. We are doing the conversion int() because it will try to multiply it as a character value otherwise; we must cast it to int.
base *= 10; // This raises the base...it's exponential but simple and uses no outside means
}
This assumes the string is only numbers. Please comment if you need more clarification.
Upvotes: 0