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

Posted

技术标签:

【中文标题】如何将命令行参数转换为 int?【英文标题】:How to convert a command-line argument to int? 【发布时间】:2011-02-17 09:00:54 【问题描述】:

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


【问题讨论】:

【参考方案1】:

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

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 &gt;= 2。都接受前导空格;如果您不想要,请查看isspace(argv[1][0])。除了atoi 之外的所有内容都拒绝尾随空格。

【讨论】:

我建议不要使用 atoi:“ atoi() 函数已被 strtol() 弃用,不应在新代码中使用。” 如果无法判断使用atoi 是否确实发生了转换,那又如何呢?对我来说,这似乎是避免atoi 的一个很好的理由。 @WhirlWind 被谁弃用了? @DrumM OP 在问题中有using namespace std; 既然我们有这个解决方案,您介意添加stoi 解决方案吗?这将使这个答案更完整。【参考方案2】:

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

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

 

【讨论】:

【参考方案3】:

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;
    

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

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

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

请注意,strtol 确实给出了稍微更详细的结果——特别是,如果你有一个像 123abc 这样的参数,sscanf 调用只会说它已经转换了一个数字 (123),而 @987654331 @ 不仅会告诉您它已经转换了数字,而且还会告诉您指向 a 的指针(即,它可以转换为数字的部分的开头)。

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

【讨论】:

【参考方案6】:

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

【讨论】:

哦,哎呀,那是我的错误。我最初是这样的,但后来开始尝试不同的东西,却忘了改回来。【参考方案7】:

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

【讨论】:

以上是关于如何将命令行参数转换为 int?的主要内容,如果未能解决你的问题,请参考以下文章

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

将命令行参数转换为 Bash 中的数组

将命令行参数转换为字符串

如何在C++中解析命令行参数

从命令行参数 C 将十六进制转换为二进制

Ghostscript将pdf转换为pdf命令行参数不起作用