Is there a TryParse equivalent in C++ (gcc)?

前端 未结 4 2042
滥情空心
滥情空心 2021-01-15 15:48

Is there a equivalent of TryParse in C++(gcc) ?

I would like to parse a string which may contain (+31321) and store it as long. I know phone numbers are stored as st

相关标签:
4条回答
  • 2021-01-15 16:08

    The trouble with strtoul() and family there is no real way to test for failure.
    If it fails to parse then it returns 0 without setting errno (which is only set on overflow).

    boost lexical cast

    #include <boost/lexical_cast.hpp>
    
    
    int main()
    {
        try
        {
            long x = boost::lexical_cast<long>("+1234");
            std::cout << "X is " << x << "\n";
        }
        catch(...)
        {
            std::cout << "Failed\n";
        }
    }
    

    Doing it using streams

    int main()
    {
        try
        {
            std::stringstream stream("+1234");
            long x;
            char test;
    
            if ((!(stream >> x)) || (stream >> test))
            {
                // You should test that the stream into x worked.
                // You should also test that there is nothing left in the stream
                //    Above: if (stream >> test) is good then there was content left after the long
                //           This is an indication that the value you were parsing is not a number.
                throw std::runtime_error("Failed");
            }
            std::cout << "X is " << x << "\n";
        }
        catch(...)
        {
            std::cout << "Failed\n";
        }
    }
    

    Using scanf:

    int main()
    {
        try
        {
            char integer[] = "+1234";
            long x;
            int  len;
    
            if (sscanf(integer, "%ld%n", &x, &len) != 1 || (len != strlen(integer)))
            {
                // Check the scanf worked.
                // Also check the scanf() read everything from the string.
                // If there was anything left it indicates a failure.
                throw std::runtime_error("Failed");
            }
            std::cout << "X is " << x << "\n";
        }
        catch(...)
        {
            std::cout << "Failed\n";
        }
    }
    
    0 讨论(0)
  • 2021-01-15 16:18

    the input extraction operator >> (i hope it's an acceptable name) applies and returns a stream&, that has a bool operator, meaning the extraction has been succesfully attempted. For instance, from the Cubbi answer:

    ...
        std::istringstream s("+31321");
        long n;
        if (s >> n)
          std::cout << n << '\n';
    ....
    

    This will succed, of course, given the appropriate content of s.

    Somewhat different (easier but not type safe) also the scanf family has practical tools available in c++ as well c. You could of course write the example this way:

    ...
        long n;
        if (sscanf("+31321", "%d", &n) == 1)
          std::cout << n << '\n';
    ...
    

    A subset of regular expressions make this rather powerful: for instance to match a comma separed multi fields with left space trimming:

       if (sscanf("a,b,c", " [^,], [^,], [^,]", a,b,c) == 3) ...
    
    0 讨论(0)
  • 2021-01-15 16:22

    In fact, before convert the string into a number, the numbers should be "normalized" to a common format. This requires removing all symbols, and replace them with proper representation.

    But you must be very care about representing telephone numbers (that are NOT numbers: they are not subjected to regular arithmetic) as string: Number beginning with one or more zeroes are not the same as the ones with the zeroes removed:

    00 is the typical replacement for +, but a number without the 00 (or +) in front should be prefixed by 00c where c is the country code.

    You need to do some pre-processing to come to a uniform string representation, before converting, otherwise you risk to "alias" different things.

    0 讨论(0)
  • 2021-01-15 16:34

    +31321 can be parsed as a long with the usual stream extraction operators.

    #include <iostream>
    #include <sstream>
    int main()
    {
        std::istringstream s("+31321");
        long n;
        s >> n;
        std::cout << n << '\n';
    }
    

    demo: http://ideone.com/4rmlp

    Although parsing an actual phone number (with parentheses, dashes, extensions, etc) may not be as simple.

    0 讨论(0)
提交回复
热议问题