c++ - 强制 String to int 函数消耗整个字符串

标签 c++ string atoi string-conversion extraction-operator

给定一个应该代表数字的字符串,我想将它放入一个转换函数中,如果整个字符串没有转换,该函数将提供通知。

对于输入:“12”:

  • istringstream::operator>> 输出 12
  • atoi 输出 12
  • stoi 输出 12

对于输入 "1X" 我想要一个失败响应,但我得到:

  • istringstream::operator>> 输出 1
  • atoi 输出 1
  • stoi 输出 1

对于输入 "X2":

  • istringstream::operator>> 输出 0 并设置错误标志
  • atoi 输出 0
  • stoi 抛出错误

[ Live Example ]

有没有办法在输入 "1X" 时引发错误行为?

最佳答案

编辑或更高版本 from_chars 是首选。更多信息请看这里:https://topanswers.xyz/cplusplus?q=724#a839


对于给定的string str,有几种方法可以实现,每种方法各有优缺点。我在这里写了一个实例:https://ideone.com/LO2Qnq并在下面讨论每一个:

strtol

按照建议here strtol 的输出参数可用于获取读取的字符数。 strtol 实际上返回的是 long 而不是 int,因此在返回时发生了转换。

char* size;
const int num = strtol(str.c_str(), &size, 10);

if(distance(str.c_str(), const_cast<const char*>(size)) == str.size()) {
    cout << "strtol: " << num << endl;
} else {
    cout << "strtol: error\n";
}

请注意,这使用 str.c_str() 来引用相同的字符串。 c_str如果您有 C++11,则返回指向用作字符存储的底层数组的指针,而不是临时数组:

c_str() and data() perform the same function

另请注意,c_str 返回的指针在 strtoldistance 调用之间有效,除非:

  • Passing a non-const reference to the string to any standard library function
  • Calling non-const member functions on the string, excluding operator[], at(), front(), back(), begin(), rbegin(), end() and rend()

如果您违反了这些情况中的任何一种,您将需要制作 i 的底层 const char* 的临时拷贝并对其执行测试。

sscanf

sscanf 可以使用 %zn 返回读取的字符数,这可能比做指针比较更直观。如果 base 很重要,sscanf 可能不是一个好的选择。与支持 2 - 36 进制的 strtolstoi 不同,sscanf 仅提供八进制说明符 (%o),十进制 (%d) 和十六进制 (%x)。

size_t size;
int num;

if(sscanf(str.c_str(), "%d%zn", &num, &size) == 1 && size == str.size()) {
    cout << "sscanf: " << num << endl;
} else {
    cout << "sscanf: error\n";
}

stoi

按照建议here stoi 的输出参数与 sscanf%n 返回读取的字符数类似。为了与 C++ 保持一致,这需要一个 string 并且与上面的 C 实现不同 stoi 抛出一个 invalid_argument如果第一个非空白字符不被认为是当前基数的数字,不幸的是,这意味着与 C 实现不同,这必须检查 trycatch block 。

try {
    size_t size;
    const auto num = stoi(str, &size);

    if(size == str.size()) {
        cout << "stoi: " << num << endl;
    } else {
        throw invalid_argument("invalid stoi argument");
    }
} catch(const invalid_argument& /*e*/) {
    cout << "stoi: error\n";
}

关于c++ - 强制 String to int 函数消耗整个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32991193/

相关文章:

android - 将字符串修剪为特定字符

c - 总结命令行

c++ -++argv 是什么? &令人困惑的编译器错误

c++ - 在 C++ 中的主线程中安排工作作业并接收回调

c++ - 如何绘制近似于原始曲线的曲线

c++ - 在 C++ 中读取 RAW 图像或 RAW 图像有标题吗?

c - 为什么字符串到 int 的转换在第一个索引时不打印数字 0

c++ - SFINAE 在 decltype 中使用范围解析运算符

java - 替换字符串中的字符,Java

javascript - 使用javascript附加问题更改每个单词的第一个字母的字体大小