CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jun 2001
    Location
    Switzerland
    Posts
    4,443

    C++ String: How to convert a string into a numeric type?

    Q: How to convert a string into a numeric type?

    A: There is one thing that you are not allowed to ignore when you convert a string into a numeric type: the conversion might fail because the
    string you are converting might not contain a valid representation of a number.

    If, for example, you try to convert the string "Hello" to a number, the conversion must fail.

    The old C way (deprecated):

    Many people use the 'atoi()', 'atof()' and the other functions from this "family". They're easy to use but have a major drawback: they return 0 both on failure and when converting the string "0", thus making a consistent error detection as good as impossible. We give this little sample for the sake of completeness:

    Code:
    const char* str_int = "777";
    const char* str_float = "333.3";
    int i = atoi(str_int);
    float f = atof(str_float);
    A better way:

    A bit more complicated, but also more consistent way is to use 'sscanf()' in one of it's flavors:

    Code:
    const char* str_int = "777";
    const char* str_float = "333.3";
    int i;
    float f;
    
    if(EOF == sscanf(str_int, "%d", &i))
    {
      //error
    }
    
    if(EOF == sscanf(str_float, "%f", &f))
    {
      //error
    }
    Since 'sscanf()' takes a 'const char*' parameter, you can directly use a 'CString' with it:

    Code:
    CString str_int("777");
    
    if(EOF == sscanf(str_int, '%d', &i))
    {
      //error
    }
    Be very careful with the format specifier (i.e. "%d" in this example). 'sscanf()' has no way to check whether the format specifier and the type of the passed variable match each other. If they don't you will get unexpected
    results. Also note that 'sscanf()' is able to extract more than one numerical value from a string with one call. Have a look in e.g. MSDN for details.


    The C++ way

    Following sample shows a template function that uses Standard C++ classes to complete the task:

    Code:
    #include <string>
    #include <sstream>
    #include <iostream>
    
    template <class T>
    bool from_string(T& t, 
                     const std::string& s, 
                     std::ios_base& (*f)(std::ios_base&))
    {
      std::istringstream iss(s);
      return !(iss >> f >> t).fail();
    }
    
    int main()
    {
      int i;
      float f;
      
      // the third parameter of from_string() should be 
      // one of std::hex, std::dec or std::oct
      if(from_string<int>(i, std::string("ff"), std::hex))
      {
        std::cout << i << std::endl;
      }
      else
      {
        std::cout << "from_string failed" << std::endl;
      }
      
      if(from_string<float>(f, std::string("123.456"), std::dec))
      {
        std::cout << f << std::endl;
      }
      else
      {
        std::cout << "from_string failed" << std::endl;
      }
      return 0;
    } 
    
    /* output:
    255
    123.456
    */
    This method is not only elegant but also type safe, because the compiler will pick the proper 'std::istringstream::operator >>()' at compile time, according to the operand type.


    Last edited by Andreas Masur; July 24th, 2005 at 12:22 PM.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: C++ String: How to convert a string into a numeric type?

    An addition to the FAQ:

    The other routine to convert is strtod(). If converting from a string to a floating point type, the usage of 'strtod()' is much safer than 'sscanf()', since

    1) the issue of providing the wrong floating point type in the argument list is eliminated, and

    2) 'strtod()' will detect if and where a string contains invalid numeric data, and return a pointer to the invalid character in the string (if the string is an invalid numeric string).

    If strictly converting from a string to floating point value, 'strtod()' should be recommended instead of 'sscanf()'.

    As a matter of fact, any string-to-numeric function that returns the result (as opposed to you giving the address of a variable for 'sscanf()' to manipulate and possibly crash) is preferable. At least with a return value, you can cast it appropriately, or the built-in C or C++ promotion rules will assign the value correctly.


    Last edited by Andreas Masur; July 24th, 2005 at 12:23 PM.

  3. #3
    Join Date
    Aug 2001
    Location
    Germany
    Posts
    1,384

    Re: Strings: How to convert a string into a numeric type?

    In addition to the above posted comments, an easier & also liable-to-be-standard is boost.org's boost::lexical_cast. Here is an excerpt from the the documentation...

    Quote Originally Posted by boost.org
    lexical_cast is for converting data from one streamable type to another, and it competes more directly with C's atoi() et al. conversion functions as well as with the nonstandard but commonly available itoa() et al. functions.
    And also an example shamelessly copied from boost.org...

    Code:
    int main(int argc, char* argv[])
    {
      using boost::lexical_cast;
      using boost::bad_lexical_cast;
    
      std::vector<short> args;
    
      while(*++argv)
      {
        try
        {
          args.push_back(lexical_cast<short>(*argv));
        }
        catch(bad_lexical_cast&)
        {
          args.push_back(0);
        }
      }
      ...
    }
    For more info, visit 'boost::lexical_cast'.


    Last edited by Andreas Masur; July 24th, 2005 at 12:25 PM.

  4. #4
    Join Date
    Jun 2002
    Posts
    137

    Re: C++ String: How to convert a string into a numeric type?

    In addition to FAQ:

    Please note that using function sccanf() to convert string into f with float type,
    Code:
    sscanf(str_float, "%f", &f);
    The result may not be what you want.
    refer to the example of FAQ:
    Code:
    printf("f is now = %f\n", f);
    You will find the out is: f is now = 333.299988

    The myth here is sccanf actually convert str_float into double type. if you cast it back to float, there will be some differences, because the way floating point is represented. See this FAQ for more.

  5. #5
    Join Date
    Sep 2008
    Posts
    22

    Re: C++ String: How to convert a string into a numeric type?

    Another one easy solution :
    • conversion to string:
      Code:
      template<class T>
          std::string toString(const T& t)
      {
           std::ostringstream stream;
           stream << t;
           return stream.str();
      }
    • conversion from string:
      Code:
      template<class T>
          T fromString(const std::string& s)
      {
           std::istringstream stream (s);
           T t;
           stream >> t;
           return t;
      }
    Last edited by ovidiucucu; June 19th, 2009 at 03:40 AM. Reason: added list, [CODE] and [/CODE] tags

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured