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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2797813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:43:44  来源:igfitidea点击:

How to convert a command-line argument to int?

c++argument-passingcommand-line-arguments

提问by nosedive25

I need to get an argument and convert it to an int. Here is my code so far:

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

}

回答by Thomas

Since this answer was somehow accepted and thus will appear at the top, although it's not the best, I've improved it based on the other answers and the comments.

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

The C way; simplest, but will treat any invalid number as 0:

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

#include <cstdlib>

int x = atoi(argv[1]);

The C way with input checking:

带有输入检查的 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';
}

The C++ iostreams way with input checking:

带有输入检查的 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';
}

Alternative C++ way since C++11:

自 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';
}

All four variants assume that argc >= 2. All accept leading whitespace; check isspace(argv[1][0])if you don't want that. All except atoireject trailing whitespace.

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

回答by CB Bailey

Note that your mainarguments are not correct. The standard form should be:

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

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

or equivalently:

或等效地:

int main(int argc, char **argv)

There are many ways to achieve the conversion. This is one approach:

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

#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;
}

回答by HelloWorld

std::stoi from string could also be used.

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

    #include <string>

    using namespace std;

    int main (int argc, char** argv)
    {
         if (argc >= 2)
         {
             int val = stoi(argv[1]);
             // ...    
         }
         return 0;
    }

回答by Jerry Coffin

As WhirlWind has pointed out, the recommendations to use atoiaren't really very good. atoihas no way to indicate an error, so you get the same return from atoi("0");as you do from atoi("abc");. The first is clearly meaningful, but the second is a clear error.

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

He also recommended strtol, which is perfectly fine, if a little bit clumsy. Another possibility would be to use sscanf, something like:

他还推荐了strtol,这很好,如果有点笨拙。另一种可能性是使用sscanf,例如:

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

note that strtoldoes give slightly more detailed results though -- in particular, if you got an argument like 123abc, the sscanfcall would simply say it had converted a number (123), whereas strtolwould not only tel you it had converted the number, but also a pointer to the a(i.e., the beginning of the part it could notconvert to a number).

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

Since you're using C++, you could also consider using boost::lexical_cast. This is almost as simple to use as atoi, but also provides (roughly) the same level of detail in reporting errors as strtol. The biggest expense is that it can throw exceptions, so to use it your code has to be exception-safe. If you're writing C++, you should do that anyway, but it kind of forces the issue.

由于您使用的是 C++,因此您也可以考虑使用boost::lexical_cast. 这几乎与 使用一样简单atoi,但在报告错误方面也提供(大致)与 相同级别的详细信息strtol。最大的开销是它可以抛出异常,所以要使用它,你的代码必须是异常安全的。如果您正在编写 C++,无论如何您都应该这样做,但这有点强迫问题。

回答by gentooise

The approach with istringstream can be improved in order to check that no other characters have been inserted after the expected argument:

可以改进使用 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;
}

回答by WhirlWind

Take a look at strtol(), if you're using the C standard library.

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

回答by Ramanand Yadav

Like that we can do....

这样我们就可以......

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]);

 }