如何将命令行参数转换为 int?

我需要得到一个参数并将其转换为 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


}
185812 次浏览

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

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

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 + + 的输入检查方式:

#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以外的所有空格都拒绝尾随空格。

请注意,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;
}

正如 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。这几乎和 atoi一样容易使用,但是在报告错误方面提供了(大致)与 strtol相同的详细信息。最大的开销是它可以抛出异常,因此要使用它,您的代码必须是异常安全的。如果你正在编写 C + + ,你无论如何都应该这样做,但是这有点强迫问题。

使用 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;
}

也可以使用 std: : stoi from string。

    #include <string>


using namespace std;


int main (int argc, char** argv)
{
if (argc >= 2)
{
int val = stoi(argv[1]);
// ...
}
return 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]);


}

在我看来,这是传递变量的最实用的方法。使用 std: : stoi。最好使用 std: : 和 NOT 来使用名称空间; 这就是为什么我可以用“ string”作为变量名来定义字符串

#include <iostream>
#include <string>


int main(int argc, char **argv)
{
std::string string{argv[1]};
int integer1{std::stoi(argv[2])};
int integer2{std::stoi(argv[3])};


int sum{integer1 + integer2};
std::cout << string << " sum " << sum;
}

例如:

./out this 40 1  // input
this sum 41      // output