Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The numeric conversion functions in the STL are terrible. They will happily accept strings with non-numeric characters in them: they will convert "123abc" to 123 without giving an error. The std::sto* functions will also ignore leading whitespace.

Yes, you can ask the std::sto* functions for the position where they stopped because of invalid characters and see if that position is the end of the string, but that is much more complex than should be needed for something like that.

These functions don't convert a string to a number, they try to extract a number from a string. I would argue that most of the time, that's not what you want. Or at least, most of the time it's not what I need.

atoi has the same problem of course, but even worse.



Now there is also std::from_chars function


std::from_chars will still accept "123abc". You have to manually check if all parts of the string have been consumed. On the other hand, " 123" is not accepted, because it starts with an invalid character, so the behaviour isn't "take the first acceptable number and parse that" either.

To get the equivalent of Rust's

    if let Ok(x) = input.parse::<i32>() {
         println!("You entered {x}");
    } else {
        eprintln!("You did not enter a number");
    }
you need something like:

     int x{};
     auto [ptr, ec] = std::from_chars(input.data(), input.data() + input.size(), x);
     if (ec == std::errc() && ptr == input.data() + input.size()) { 
         std::cout << "You entered " << x << std::endl;
     } else {
         std::cerr << "You did not enter a valid number" << std::endl;
     }
I find the choice to always require a start and and end position, and not to provide a method that simply passes or fails, to be quite baffling. In C++26, they also added an automatic boolean conversion for from_chars' return type to indicate success, which considers "only consumed half the input from the start" to be a success.

Maybe I'm weird for mostly writing code that does straightforward input-to-number conversions and not partial string parsers, but I have yet to see a good alternative for Rust's parse().


I guess there's a place for functions that extract or parse partially, but IMO there is a real need for an actual conversion function like Rust's parse() or Python's int() or float(). I think it's a real shame C++ (and C as well) only offers the first and not the second.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: