I am trying to convert wstring_view to int. Is there something like stoi that works on wstring_view instead of string? Can't use any C-api's since it's not necessarily null-terminated. Can't use from_chars since it's wchar_t. So far, I've been converting to std::wstring, then converting to int (using stoi), which is probably OK with small string optimizations and all, but goes against the point of using views in the first place.
convert wstring_view to int
896 Views Asked by Aykhan Hagverdili At
2
There are 2 best solutions below
0
On
Here's what I found that works:
#include <cwchar>
#include <optional>
#include <string_view>
std::optional<int> StrToInt(std::wstring_view const view) noexcept {
wchar_t format_str[13]; // % + 10digits + d + \0 = 13 characters
std::swprintf(format_str, std::size(format_str), L"%%%dd", (int)view.size());
int res;
if (std::swscanf(view.data(), format_str, &res) != 1) return std::nullopt;
return res;
}
Since we specify the size explicitly in format_str, view doesn't need to be null-terminated.
If we have verified that the string only contains numeric characters (no sign character, no leading or trailing spaces, etc.) and it won't overflow, we can use a simpler unchecked routine:
int UncheckedStrToInt(std::wstring_view const str) noexcept {
int res = 0;
for (auto ch : str)
res = res * 10 + (ch - '0');
return res;
}
I did some benchmarks. The swscanf performs much worse than stoi. I will be using stoi or UncheckedStrToInt depending on if the wstring_view is already verified.

std::stoi(std::wstring)is just a wrapper forstd::wcstol(), which you can call directly. However, it requires a null-terminatedwchar_t*string, butstd::wstring_viewis not guaranteed to be null-terminated, as you noted.Since a 32bit
inthas a maximum of 10 decimal digits, plus an optional sign, plus the null-terminator, you could simply copy thestd::wstring_viewdata into a localwchar_t[12]array, null-terminate it, and then convert that withstd::wcstol(),std::swscanf(), etc.Alternatively, you can create a custom
FILE*stream that reads from thestd::wstring_viewdata, such as viafmemopen()or equivalent, and then you can usestd::fwscanf().Alternatively, you can write a (or find a 3rd party) custom
std::basic_streambuf-derived class that reads from thestd::wstring_view, and then you can give an instance of that class to a standardstd::istreamobject and use itsoperator>>to extract theint.