-
March 9th, 2010, 01:37 PM
#1
Convert string to int
Presently, I am using the atoi() function. But I don't want to use this because if the user inputs a value that isn't numeric, it returns 0. So I can't really check if they entered an actual 0 or an incorrect value. What are alternatives to using atoi?
-
March 9th, 2010, 01:45 PM
#2
Re: Convert string to int
You could use strtol(). It takes a pointer to the part that failed. You can use pointer arithmetic to determine how the conversion proceded:
http://msdn.microsoft.com/en-us/libr...8VS.80%29.aspx
Or just use a std::stringstream
-
March 9th, 2010, 02:02 PM
#3
Re: Convert string to int
Originally Posted by SterlingM
Presently, I am using the atoi() function. But I don't want to use this because if the user inputs a value that isn't numeric, it returns 0. So I can't really check if they entered an actual 0 or an incorrect value. What are alternatives to using atoi?
strtol() for long int
strtoul() for long unsigned int
strtod() for double
-
March 9th, 2010, 02:08 PM
#4
Re: Convert string to int
If you are using C++, you could use boost lexical. If you are using C++, but don't want to be dependent on boost, then you could use stringstream to write your own conversion function. For example, this should do what you need:
Code:
template <typename T>
T string_to(const std::string &s)
{
T result;
//check for the boolean 'true' keyword
if (s.find("true")!=std::string::npos)
{
result = 1;
}
//check for the boolean 'false' keyword
else if (s.find("false")!=std::string::npos)
{
result=0;
}
else
{
std::stringstream ss;
//Check for Hex input
if(s.size()>1)
{
//If the first two characters are '0x' then the input is
//a hexidecimal input and therefore the stringstream
//base needs to be set to base 16.
if(s[0]=='0' && tolower(s[1])=='x')
{
ss << std::setbase(16);
}
}
ss.str(s);
if (!(ss >> result))
{
throw std::runtime_error("string_to: Failed to convert string to destination type");
}
}
//Return the resulting value.
return result;
}
You can use it like:
Code:
int value = string_to<int>("123");
The above works for conversions from a string to other types too (bool, float etc...).
-
March 9th, 2010, 02:17 PM
#5
Re: Convert string to int
I wrote this for a scripting language. It converts them to long doubles, but you can cast that down to an int easily. Admittedly, it's a little messy, but it's stable and fast. I probably send a million conversions through it a week.
Code:
/*
* Number_Functions.cpp
* Math
*
* Created by Wallace on 12/5/09.
* Copyright 2009 LiveTechnology. All rights reserved.
*
*/
#include "Number_Functions.h"
#include <sstream>
#include <iomanip>
#include <cmath>
#include <iostream>
string LS_INFINITY = "Infinity";
string NEG_LS_INFINITY = "-Infinity";
string LS_UNDEFINED = "NaN";
long double Infinity = 1.0f / 0.0f;
long double NaN = sqrt(-1);
long double e = 2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274f;
long double pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679f;
char NumberChars[] = {"0123456789"};
char HexChars[] = {"012345679ABCDEFabcdef"};
int Fixed_Precision = 12;
long double StringToHex(const string & str){
long long tout = 0;
char * p = (char*)str.c_str();
p += 2; //go past the 0 and x
while(*p){
tout = tout << 4; //a hex character represents 4 bits
unsigned char ch = *p;
if (ch < 58){ //0-9
tout |= ch - 48;
} else if (ch < 71){ //A-F
tout |= ch - 55;
} else { //a-f
tout |= ch - 87;
}
++p;
}
return (long double)tout;
}
long double PercentToNumber(const string & s, size_t len, const long double & outof){
//len is the length of the NUMBER (exclusing the %)
long double res = atof(s.substr(0, len).c_str());
return res * outof / 100.0f;
}
bool NumberFunctions::CheckNonNumberChar(const string & str, size_t pp, long double & out, const long double & outof, bool AllowDecimals){
/*
This is for when it found a character that is not numeric, it could still be
scientific notation
a decimal place
a percentage
*/
switch (str[pp]){
case 'e': //scientific notation, or just an e?
switch (str[pp + 1]){
case '+':
if (str.find_first_not_of(NumberChars, pp + 2) == string::npos){
out = atof(str.c_str());
return true;
}
break;
case '-': //initial negation was already compensated for, so pp can never be 0
if (str.find_first_not_of(NumberChars, pp + 2) == string::npos){
out = atof(str.c_str());
return true;
}
break;
}
break;
case '.':
if (!AllowDecimals) return false; //already been through this once, it's the second decimal
pp = str.find_first_not_of(NumberChars, pp + 1);
if (pp == string::npos) return true;
return CheckNonNumberChar(str, pp, out, outof, false);
case '%':
size_t len = str.length();
if (pp == len){
out = PercentToNumber(str, len, outof);
return true;
}
}
return false;
}
string NumberFunctions::ToString(long double n){
if (n == Infinity) return LS_INFINITY;
if (n == -Infinity) return NEG_LS_INFINITY;
stringstream out;
out << setprecision(Fixed_Precision) << n;
return out.str();
}
/*
<x> = (0-9)
<h> = (<x> | (A-F) | (a-f))*
<d> = (<x>*).(<x>*)
<c> = Pi | PI | pi | e
Number = ([-](<d> | Infinity | 0x<h> | <d>e[-]<x>)) | NaN | <c>
*/
long double NumberFunctions::ToNumber(const string & s, const long double & outof){
if (s == "e") return e;
if ((s == "Pi") || (s == "pi") || (s == "PI")) return pi;
return ToNumber_NoConstants(s, outof);
}
long double NumberFunctions::ToNumber_NoConstants(const string & s, const long double & outof){
if (((s[0] == '0') && (s[1] == 'x')) ||
((s[0] == '-') && (s[1] == '0') && (s[2] == 'x'))){
return StringToHex(s);
} else {
size_t len = s.length() - 1;
if (s[len] == '%'){
return PercentToNumber(s, len, outof);
}
}
if (s == LS_INFINITY) return Infinity;
if (s == NEG_LS_INFINITY) return -Infinity;
if (s == LS_UNDEFINED) return NaN;
return atof(s.c_str());
}
bool NumberFunctions::IsNumber(const string & str, long double & out, const long double & outof){
if (str == "e"){
out = e;
return true;
}
if ((str == "Pi") || (str == "pi") || (str == "PI")){
out = pi;
return true;
}
return IsNumber_NoConstants(str, out, outof);
}
bool NumberFunctions::IsNumber_NoConstants(const string & str, long double & out, const long double & outof){
if (str == LS_INFINITY){
out = Infinity;
return true;
}
if (str == NEG_LS_INFINITY){
out = -Infinity;
return true;
}
if (str[0] == '-'){
if ((str[1] == '0') && (str[2] == 'x')){
if (str.find_first_not_of(HexChars, 3) != string::npos) return false;
out = StringToHex(str);
return true;
} else { //negative, non hex, keep looking for failure
size_t pp = str.find_first_not_of(NumberChars, 1);
if (pp != string::npos) return CheckNonNumberChar(str, pp, out, outof);
}
} else if ((str[0] == '0') && (str[1] == 'x')){
if (str.find_first_not_of(HexChars, 2) != string::npos) return false;
out = StringToHex(str);
return true;
} else {
size_t pp = str.find_first_not_of(NumberChars);
if (pp != string::npos) return CheckNonNumberChar(str, pp, out, outof);
}
out = atof(str.c_str());
return true;
}
Here is the grammar:
Code:
<x> = (0-9)
<h> = (<x> | (A-F) | (a-f))*
<d> = (<x>*).(<x>*)
<c> = Pi | PI | pi | e
Number = ([-](<d> | Infinity | 0x<h> | <d>e[-]<x>)) | NaN | <c>
No octal support, but I've never actually seen a programmer use an octal value :\
Last edited by ninja9578; March 9th, 2010 at 02:20 PM.
-
March 9th, 2010, 11:15 PM
#6
Re: Convert string to int
Originally Posted by SterlingM
Presently, I am using the atoi() function. But I don't want to use this because if the user inputs a value that isn't numeric, it returns 0. So I can't really check if they entered an actual 0 or an incorrect value. What are alternatives to using atoi?
I simple check if str is '0' would probably work.
Code:
int satoi( const char* Str, bool& Err )
{
int Num = atoi( Str );
Err = !Num && *Str != '0';
return Num;
}
or you just
Code:
int satoi( const char* Str )
{
int Num = atoi( Str );
if( !Num && *Str != '0' ) throw( "String to int failed" );
return Num;
}
0100 0111 0110 1111 0110 0100 0010 0000 0110 1001 0111 0011 0010 0000 0110 0110 0110 1111 0111 0010
0110 0101 0111 0110 0110 0101 0111 0010 0010 0001 0010 0001 0000 0000 0000 0000 0000 0000 0000 0000
-
March 9th, 2010, 11:31 PM
#7
Re: Convert string to int
Originally Posted by ninja9578
long double e = 2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274f;
long double pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679f;
I love the fact that you included about a thousand digits, and then put "f" on the end to indicate the literal should be a single-precision float, effectively discarding the majority of those digits.....
-
March 10th, 2010, 09:30 AM
#8
Re: Convert string to int
O.o Oops. Uh, that should be ld. I don't know how I missed that one :\ I think I had less digits there once, then added the others just for the hell of it.
-
March 10th, 2010, 12:09 PM
#9
Re: Convert string to int
Originally Posted by Lindley
I love the fact that you included about a thousand digits, and then put "f" on the end to indicate the literal should be a single-precision float, effectively discarding the majority of those digits.....
lol.
-
March 10th, 2010, 12:20 PM
#10
Re: Convert string to int
This is one of those questions where an appropriate answer could have been to just make a referral to the FAQ since this question is one that has been asked so often. It would save you all a lot of typing!
http://www.codeguru.com/forum/showthread.php?t=231054
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|