将 wstring_view 转换为 int

问题描述

我正在尝试将 wstring_view 转换为 int。是否有类似 stoi 的东西适用于 wstring_view 而不是 string?不能使用任何 C-api,因为它不一定以 null 结尾。不能使用 from_chars,因为它是 wchar_t。到目前为止,我一直在转换为 std::wstring,然后转换为 int(使用 stoi),这对于小字符串优化等可能没问题,但与使用的点背道而驰首先是视图。

解决方法

这是我发现有效的方法:

#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;
}

由于我们在 format_str 中明确指定了大小,因此视图不需要以 null 结尾。

如果我们已经验证字符串只包含数字字符(没有符号字符,没有前导或尾随空格等)并且不会溢出,我们可以使用更简单的未经检查的例程:

int UncheckedStrToInt(std::wstring_view const str) noexcept {
  int res = 0;
  for (auto ch : str)
    res = res * 10 + (ch - '0');
  return res;
}

我做了一些benchmarksswscanf 的性能比 stoi 差很多。我将使用 stoiUncheckedStrToInt,具体取决于 wstring_view 是否已验证。

enter image description here

,

std::stoi(std::wstring) 只是 std::wcstol() 的包装器,您可以直接调用它。但是,它需要一个以 null 结尾的 wchar_t* 字符串,但正如您所指出的,std::wstring_view 不能保证以 null 结尾。

由于 32 位 int 最多有 10 个十进制数字,加上一个可选符号,加上空终止符,您可以简单地将 std::wstring_view 数据复制到本地 wchar_t[12] 数组中,以空字符结尾,然后用 std::wcstol()std::swscanf() 等进行转换。

或者,您可以创建从 FILE* 数据读取的自定义 std::wstring_view 流,例如通过 fmemopen() 或等效方式,然后您可以使用 std::fwscanf()

或者,您可以编写一个(或找到第 3 方)自定义 std::basic_streambuf 派生类来读取 std::wstring_view,然后您可以将该类的实例提供给标准 {{ 1}} 对象并使用其 std::istream 提取 operator>>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...