问题
I'm working on a project where I want to accept an input of the form {float}{single-letter-identifier}
, for example 15.6E
, or 10W
.
To do this, I thought that I could take the input string, strip off the last letter and then check to see if a conversion could be performed to float, using std::stof
. This would be nested in a try-catch
block, and allow me to notify the user of invalid input.
The open-standard of the STL here (page 653) states that std::stof
throws:
invalid_argument
if wcstod or wcstold reports that no conversion could be performed.
However, it doesn't throw when passed something it cannot convert, e.g. "48East"
. A code sample to reproduce this behavior is below:
std::wstring szString = L"48East";
try{
float f = std::stof(szString);
} catch( ... )
{
std::cout << "test" << std::endl;
}
This is compiled on MSVC10 in debug mode with /Od
, so I'm assuming the call is not optimized away.
I'd appreciate any help (or guidance as to where I've misunderstood/misread the spec!).
回答1:
As I read it, stof
converts as much of the input string as it can until it finds something it can't convert. if it can't convert anything it throws invalid_argument
.
回答2:
The MSVC implementation parses the valid characters from the beginning and converts them successfully so your result is 48F
in the above case. If instead you had "East48"
you would get the invalid argument exception as expected.
Edit: Furthermore if you pass the optional index out parameter the function will report the index of the insignificant characters not used for the conversion. In the above example this would allow you to do something like this:
std::wstring szString = L"48East";
try{
size_t i(0);
float f = std::stof(szString, &i);
std::cout << f << szString.substr(i).c_str() << std::endl;
} catch( ... )
{
std::cout << L"test" << std::endl;
}
which produces the output 48East
来源:https://stackoverflow.com/questions/11443074/why-does-stdstof-not-throw-when-passed-an-argument-it-cannot-convert