在C++中将字符串转换为整数

8

你好,我知道这个问题被问了很多次,但我还没有找到我的具体问题的答案。

我想转换只包含十进制数字的字符串:

例如256是可以的,但256a不行。

能不能在不检查字符串的情况下完成呢?

谢谢


2
你的主题行写着“将整数转换为字符串”,但是你的问题似乎暗示了一个字符串到整数的转换... 你想做什么?! - EboMike
1
这篇文章含糊不清,需要更多的标点符号。你能举个例子解释一下你的意思吗? - JoshD
4个回答

14

我能想到的最简单的使错误检查变为可选的方法是这样的:

char *endptr;
int x = strtol(str, &endptr, 0);
int error = (*endptr != '\0');

1
我不喜欢 atoi,因为它无法区分完全无效的字符串和有效但转换为 0 的字符串。 - Evan Teran

7

使用 C++ 的方式,可以使用 stringstream

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    stringstream sstr;
    int a = -1;

    sstr << 256 << 'a';
    sstr >> a;

    if (sstr.failbit)
    {
        cout << "Either no character was extracted, or the character can't represent a proper value." << endl;
    }
    if (sstr.badbit)
    {
        cout << "Error on stream.\n";
    }

    cout << "Extracted number " << a << endl;

    return 0;
}

但如果字符串不是整数呢?a的值会是什么? - Jean-François Fabre
@Jean-FrançoisFabre:您可以通过验证sstr.rdstate()返回的状态或检查单个状态值来检查流条件。我已经更新了我的答案,提供了后一种选择。 - Donotalo

6

另一种使用C++风格的方法:我们检查数字的数量来确定字符串是否有效:

#include <iostream>
#include <sstream>
#include <string>
#include <cmath>

int main(int argc,char* argv[]) {

    std::string a("256");

    std::istringstream buffer(a);
    int number;
    buffer >> number; // OK conversion is done !
    // Let's now check if the string was valid !
    // Quick way to compute number of digits
    size_t num_of_digits = (size_t)floor( log10( abs( number ) ) ) + 1;
    if (num_of_digits!=a.length()) {
        std::cout << "Not a valid string !" << std::endl;
    }
    else {
        std::cout << "Valid conversion to " << number  << std::endl;
    }

}

对于“0”、“0001”、“-5”均失败。 - stark

0
在C++17及以上版本中,最好的方法是使用头文件charconv中的std::from_chars()。与其他解决方案不同,这个方法可以自动处理溢出,而且处理方式非常简洁。它还与区域设置无关,不需要分配内存,不会抛出异常,因此性能预计会优于基于字符串流的解决方案。您可以在cppreference中找到更多信息。
以下示例摘自cppreference。
#include <cassert>
#include <charconv>
#include <iomanip>
#include <iostream>
#include <string_view>
#include <system_error>
 
int main()
{
    for (std::string_view const str : {"1234", "15 foo", "bar", " 42", "5000000000"})
    {
        std::cout << "String: " << std::quoted(str) << ". ";
        int result{};
        auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
 
        if (ec == std::errc())
            std::cout << "Result: " << result << ", ptr -> " << std::quoted(ptr) << '\n';
        else if (ec == std::errc::invalid_argument)
            std::cout << "This is not a number.\n";
        else if (ec == std::errc::result_out_of_range)
            std::cout << "This number is larger than an int.\n";
    }
}

演示:https://godbolt.org/z/ohxWEbnTb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接