Как преобразовать аргумент командной строки в 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 argumentn");
        exit(0);
    }

    // Convert it to an int here

}

7 ответов


поскольку этот ответ был каким-то образом принят и, таким образом, появится наверху, хотя это не лучший, я улучшил его на основе других ответов и комментариев.

путь 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';
}

путь iostreams 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++ с C++11:

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

std:: stoi из строки также можно использовать.

    #include <string>

    using namespace std;

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

как отметил вихрь, рекомендации по использованию 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), тогда как strtol не только тел вам он преобразовал номер, но и указатель на a (т. е. в начале это может не преобразовать в число).

поскольку вы используете C++, вы также можете рассмотреть возможность использования boost::lexical_cast. Это почти так же просто в использовании, как atoi, но и обеспечивает (примерно) тот же уровень детализации в отчетах об ошибках, что и strtol. Самый большой расход заключается в том, что он может создавать исключения, поэтому для его использования ваш код должен быть безопасным для исключений. Если вы пишете C++, вы все равно должны это сделать, но это заставляет проблему.


взгляните на 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;
}

Как это мы можем сделать....

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

 }