77

我需要得到一个参数并将其转换为一个 int。到目前为止,这是我的代码:

#include <iostream>


using namespace std;
int main(int argc,int argvx[]) {
    int i=1;
    int answer = 23;
    int temp;

    // decode arguments
    if(argc < 2) {
        printf("You must provide at least one argument\n");
        exit(0);
    }

    // Convert it to an int here

}
4

7 回答 7

119

由于这个答案以某种方式被接受,因此会出现在顶部,虽然它不是最好的,但我已经根据其他答案和评论对其进行了改进。

C方式;最简单,但会将任何无效数字视为 0:

#include <cstdlib>

int x = atoi(argv[1]);

带有输入检查的 C 方式:

#include <cstdlib>

errno = 0;
char *endptr;
long int x = strtol(argv[1], &endptr, 10);
if (endptr == argv[1]) {
  std::cerr << "Invalid number: " << argv[1] << '\n';
} else if (*endptr) {
  std::cerr << "Trailing characters after number: " << argv[1] << '\n';
} else if (errno == ERANGE) {
  std::cerr << "Number out of range: " << argv[1] << '\n';
}

带有输入检查的 C++ iostreams 方式:

#include <sstream>

std::istringstream ss(argv[1]);
int x;
if (!(ss >> x)) {
  std::cerr << "Invalid number: " << argv[1] << '\n';
} else if (!ss.eof()) {
  std::cerr << "Trailing characters after number: " << argv[1] << '\n';
}

自 C++11 以来的替代 C++ 方式:

#include <stdexcept>
#include <string>

std::string arg = argv[1];
try {
  std::size_t pos;
  int x = std::stoi(arg, &pos);
  if (pos < arg.size()) {
    std::cerr << "Trailing characters after number: " << arg << '\n';
  }
} catch (std::invalid_argument const &ex) {
  std::cerr << "Invalid number: " << arg << '\n';
} catch (std::out_of_range const &ex) {
  std::cerr << "Number out of range: " << arg << '\n';
}

所有四个变体都假设argc >= 2. 都接受前导空格;检查isspace(argv[1][0])你是否不想要那个。除了atoi拒绝尾随空格之外的所有内容。

于 2010-05-09T13:52:37.243 回答
24

请注意,您的main论点不正确。标准格式应该是:

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

或等效地:

int main(int argc, char **argv)

有很多方法可以实现转换。这是一种方法:

#include <sstream>

int main(int argc, char *argv[])
{
    if (argc >= 2)
    {
        std::istringstream iss( argv[1] );
        int val;

        if (iss >> val)
        {
            // Conversion successful
        }
    }

    return 0;
}
于 2010-05-09T13:53:57.053 回答
19

也可以使用来自字符串的 std::stoi 。

    #include <string>

    using namespace std;

    int main (int argc, char** argv)
    {
         if (argc >= 2)
         {
             int val = stoi(argv[1]);
             // ...    
         }
         return 0;
    }
于 2016-02-22T14:24:02.760 回答
3

正如 WhirlWind 所指出的,使用的建议atoi并不是很好。atoi无法指示错误,因此您获得的回报与来自 的回报atoi("0");相同atoi("abc");。第一个显然是有意义的,但第二个是一个明显的错误。

他还推荐strtol了 ,虽然有点笨拙,但完全没问题。另一种可能性是使用sscanf,例如:

if (1==sscanf(argv[1], "%d", &temp))
    // successful conversion
else
    // couldn't convert input

请注意,它strtol确实给出了更详细的结果——特别是,如果你有一个类似的参数123abcsscanf调用只会说它已经转换了一个数字(123),而strtol它不仅会告诉你它已经转换了数字,而且指向的指针a(即,它无法转换为数字的部分的开头)。

由于您使用的是 C++,因此您也可以考虑使用boost::lexical_cast. 这几乎atoistrtol. 最大的开销是它可以抛出异常,所以要使用它,你的代码必须是异常安全的。如果您正在编写 C++,则无论如何都应该这样做,但这会迫使问题发生。

于 2010-05-09T14:41:51.637 回答
1

如果您使用的是 C 标准库,请查看 strtol()。

于 2010-05-09T13:52:02.070 回答
1

可以改进使用 istringstream 的方法,以检查在预期参数之后是否没有插入其他字符:

#include <sstream>

int main(int argc, char *argv[])
{
    if (argc >= 2)
    {
        std::istringstream iss( argv[1] );
        int val;

        if ((iss >> val) && iss.eof()) // Check eofbit
        {
            // Conversion successful
        }
    }

    return 0;
}
于 2016-02-04T16:38:03.503 回答
0

像这样我们可以做......

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

    int a, b, c;
    *// Converting string type to integer type
    // using function "atoi( argument)"* 

    a = atoi(argv[1]);     
    b = atoi(argv[2]);
    c = atoi(argv[3]);

 }
于 2018-04-08T06:53:56.493 回答