繁体   English   中英

c++ stoi 无法正确转换字符串

[英]c++ stoi doesn't convert string correctly

#include <iostream>
#include <string>

int main() {

    std::string s = "3a3";

    try
    {
        int i = std::stoi(s);
        std::cout << i << '\n';
    }
    catch (std::invalid_argument const &e)
    {
        std::cout << "Bad input: std::invalid_argument thrown" << '\n';
    }
    catch (std::out_of_range const &e)
    {
        std::cout << "Integer overflow: std::out_of_range thrown" << '\n';
    }

    return 0;
}

出来的是“3”。 前 3 后有字母表。它是如何转换的......? "10 10" 也是 10。它无法捕捉中间的空格。

快速响应:尝试:

std::stoi(s, nullptr, 16)

解释:

stoi function 有三个参数

  1. 字符串:这是包含字符串格式数字的字符串变量。
  2. Size_t:字符串中要转换的字符数量。 注意:我总是将它设置为 nullptr,因为我用它来转换整个字符串。
  3. 基数:这是写入字符串编号的基数。

您遇到的问题是,如果未提供 base , stoi 将使用其默认值(即 10,并且是最常用的基本格式)。

所以第一个问题是字符“a”不是以 10 为基数的数字,因此会引发 invalid_argument 异常。 第二个问题是由于 stoi 如何处理异常而发生的。 仅当 stoi 无法转换字符串中的任何字符时才会引发异常。 这意味着虽然至少第一个字符是有效数字(考虑到基数),但不会引发异常,而是会返回忽略第一个非基数之后的任何字符的转换。

在这种情况下,“3a3”会在字符“a”处引发异常,因为它不是以 10 为基数的数字。 然后它将转换为 integer 所有先前的字符,在这种情况下,这只是第一个字符“3”,这就是您得到该结果的原因。 不引发异常。 但是,如果字符串是“a33”,则 stoi 将无法转换 'a',因为它不是十进制数字并且会引发异常; 因为它无法转换任何数字。

为避免这种情况,我通常会逐个检查整个字符串是否是有效的数字检查。

std::string myString = "265F"
for(auto ch : myString)
{
  if(!isxdigit(ch))
    {
      throw std::invalid_argument("error message")
    }
}

该代码将检查字符串对于十六进制是否有效。 对于十进制数字,您可以使用 isdigit()。

例如,如果您有“327F”,那么stoi("327f")将返回 327。此外,重要的是要记住 bases 也会更改字符串的值。 例如,十六进制的 10 是十进制的 16。 因此,除十进制以外的任何基数的转换都需要作为参数显式传递。 如果未提供基数,则假定字符串以十进制为基数,十进制的 10 为 10。

您想要的是将基本参数设置为十六进制 (16),然后计算将接受字符 0123456789ABCDEF 和小写变体作为数字。 如果字符串以十六进制而不是十进制为基数写入,这也将返回预期值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM