1

I have the following code that works fine on my Windows machine, but not when I'm developing at home on my (M1) Mac. It is for parsing a line in a csv file into floats...

std::stringstream ss("1.0, 2.0, 3.0, 4.0"); // Example line.
std::vector<float> storedValues;

while(ss.good())
{
    std::string substring;
    std::getline(ss, substring, ',');

    float entry = std::stof(substring); // This is where it breaks.
    storedValues.push_back(entry);
}

On Windows (Visual Studio 2019) this will compile. On my machine I get the following complaint:

libc++abi: terminating with uncaught exception of type std::invalid_argument: stof: no conversion
terminating with uncaught exception of type std::invalid_argument: stof: no conversion

What is even more strange is that the following WILL work on my XCode setup, no problem:

float test = std::stof("0.1");

So I don't know. What do you think?

mhenry
  • 11
  • 2
  • 1
    That's not a compilation error. It's a runtime error. – Ted Lyngmo May 27 '22 at 21:11
  • What compiler (and version) are you using? – ChrisMM May 27 '22 at 21:13
  • 1
    Does the locale where you live use a dot or a comma as a decimal separator? – rustyx May 27 '22 at 21:26
  • @ChrisMM I'm using XCode Version 13.3.1, 13.1.6 (clang-1316.0.21.2.3) – mhenry May 27 '22 at 21:28
  • @rustyx Interesting -- I live in Quebec which does occasionally use comma for the decimal separator. But I've never seen this in code... – mhenry May 27 '22 at 21:29
  • Don't use `while(ss.good())`, it is causing the last string to be empty. Move the `substring` declaration up, out of the loop, and use `while(std::getline(ss, substring, ','))` instead. See also https://stackoverflow.com/q/4324441/1458097 – heap underrun May 27 '22 at 22:06
  • @rustyx Unless he is using some third-party libraries that mess with locale on startup, the initial locale already has `.` as the decimal separator. Quoting [`std::setlocale`](https://en.cppreference.com/w/cpp/locale/setlocale) on Cppreference: "_During program startup, the equivalent of std::setlocale(LC_ALL, "C"); is executed before any user code is run._" – heap underrun May 27 '22 at 22:36

1 Answers1

1

This seems to be because you are attempting to convert "" (empty string) to float.

As you can see here, VS terminates prior to printing the float and returns an exit code, while g++ and clang throw.

As mentioned in the comments, using ss.good() as the loop condition is actually a problem. See here for more information. Essentially though, the last time through the loop, your string substring ends up being empty. Thus, when passed to stof, it should throw.

stof should throw an std::invalid_argument if no conversion can be performed (see cppreference); which is what should happen for empty strings.

ChrisMM
  • 7,552
  • 11
  • 27
  • 44
  • No, MSVC does not allow empty string conversion to float. Your example code on Godbolt shows that the program exited with error code `3221226505` (or `0xC0000409` in hex), which is [`STATUS_FAIL_FAST_EXCEPTION`](https://docs.microsoft.com/en-us/shows/inside/c0000409). Basically, due to uncaught C++ exception. See [another example](https://godbolt.org/z/cKxccd5je), which shows it is an `std::invalid_argument` exception (with "invalid stof argument" in its explanatory text). – heap underrun May 28 '22 at 00:09
  • @heapunderrun, you're right, I didn't pay much attention to the output when running and just saw that it wasn't the same exception that was printed like the other two. – ChrisMM May 28 '22 at 00:23