Skip to content

Beginner Gotchas

The Number With Units

a numeric parse that quietly accepts ms

int main() {
  const std::string timeout = "30ms";

  std::cout << "seconds: " << std::stoi(timeout) << '\n';
}

Does stoi reject the trailing unit?

Answer
seconds: 30

The ms suffix was ignored.

Why

std::stoi deliberately converts the longest valid numeric prefix. It throws when no conversion is possible or the result is out of range, not merely because text remains after a valid number. Its optional pos argument reports the index of the first unconverted character. Check that index when the input must be a whole number.

The fix

std::size_t used = 0;
const int seconds = std::stoi(timeout, &used);
if (used != timeout.size())
  std::cerr << "invalid timeout\n";

Takeaway: a successful stoi call only proves that a valid number was found after optional leading whitespace; compare pos with the string size to validate all of it.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry