Unable to call `std::stoi` on split string

22 hours ago 1
ARTICLE AD BOX

Checkout some API in standard library which makes this quick and easy:

import std; int main() { std::ifstream f{"data.txt"}; auto v = std::views::istream<int>(f) | std::ranges::to<std::vector>(); std::println("v = {}", v); return 0; } std::views::istream std::ranges::to or old fashion: std::istream_iterator

Here is live demo.

Note that underneath it uses stream operator operator>>(std::istream&, target_type). So if you like to use some custom type you should provide stream operator for that type.

Marek R's user avatar

1 Comment

istream_iterator may be old fashioned, but seems rather more straightforward for this particular case. std::vector<int> v{std::istream_iterator<int>(f),{}};.

2026-05-14T15:02:34.547Z+00:00

From the split, you get a range, not a string. Here's how to do that:

#include <iostream> #include <ranges> #include <string> #include <vector> int main() { std::string input = "10 20 30 40"; std::vector<int> data = input | std::views::split(' ') | std::views::transform([](auto&& chunk) { int result = 0; auto [ptr, ec] = std::from_chars( chunk.data(), chunk.data() + chunk.size(), result); if (ec != std::errc{}) { throw std::runtime_error{"Failed to parse int"}; } return result; }) | std::ranges::to<std::vector>(); for (int e : data) { std::cout << e << '\n'; } }

Aykhan Hagverdili's user avatar

If you prefer to work with line in string, then another solution to your problem is to use std::generator. This mixes well with std::from_chars.

import std; template <std::integral Int> auto parse_ints_from(std::string_view in, int base = 10) -> std::generator<Int> { auto b = in.data(); auto e = b + in.size(); while (b != e) { while (b != e && std::isspace(*b)) { ++b; } if (b == e) { break; } Int result = 0; auto [ptr, ec] = std::from_chars(b, e, result, base); if (ec != std::errc{}) { throw std::invalid_argument{"parse failure"}; } co_yield result; b = ptr; } } int main() try { constexpr std::string_view line = "13 21 -32 23 "; auto v = parse_ints_from<int>(line) | std::ranges::to<std::vector>(); std::println("v = {}", v); } catch (const std::exception& e) { std::println(std::cerr, "Exception: {}", e.what()); return 1; }

https://godbolt.org/z/5j5MheKWK

Marek R's user avatar

1 Comment

Would it be better to throw std::system_error{ec};?

2026-05-14T17:28:11.07Z+00:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Read Entire Article