Как получить входные данные из argv [] за пределами основного переполнения стека

В настоящее время я пытаюсь взять число с argv [] из командной строки.
Другими словами, я пытаюсь получить 2 из

./ калькулятор -q 2

Моя текущая установка что-то вроде:

#include <iostream>
using namespace std;

int check_q(char* argv[]){
float q, qa;
if(atoi(argv[1]) == q){
qa = atof(argv[2]);
}
if(atoi(argv[3]) == q){
qa = atof(argv[4]);
}
if(atoi(argv[5]) == q){
qa = atof(argv[6]);
}
if(atoi(argv[7]) == q){
qa = atof(argv[8]);
}
return qa;
}

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

float qa = 0;
check_q(argv);
cout << qa << endl;

return 0;}

Есть идеи, что я делаю не так?

2

Решение

Вы не проверяете значение argc чтобы увидеть, сколько аргументов было передано программе. Если вы передаете только два аргумента, то доступ argv[3] даст неопределенное поведение; поэтому вы должны сначала проверить количество аргументов.

Кроме того, если вы ищете аргумент со значением "-q"затем сравните с "-q":

if (std::string(argv[1]) == "-q")

Вы конвертируете его в число и сравниваете его с неинициализированной переменной, которая ничего не даст.

2

Другие решения

Передайте это:

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cassert>

float check_q(std::vector<std::string> const& args)
{
int q = 42;

for (auto it = args.begin(); it != args.end(); std::advance(it, 2))
{
if (std::stoi(*it) == q)
{
auto next = std::next(it);
assert(next != args.end());

return std::stof(*next);
}
}

return 0;
}int main(int argc, const char *argv[])
{
const std::vector<std::string> args(argv, argv+argc);

// pass it along
check_q(args);
}
2

Вы делаете что-то неправильно здесь:

#include <iostream>
using namespace std;

int check_q(char* argv[])
{
float q, qa;           // you never assign `q` a value, so the following comparisons make no sense
if(atoi(argv[1]) == q)   // you never check argc in main to determine if argv[whatever] is valid.  if the array isn't long enough, this will invoke undefined behavior.
{
qa = atof(argv[2]);  // you're assigning a value to `qa` declared in this function, leaving the one declared in main unchanged.  probably not what you intended
}
// and so on

return qa;
}

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

float qa = 0;
check_q(argv);    // this function never changes the value of `qa` that's declared in main...
cout << qa << endl;    // ... so this will always print 0

return 0;

}

Вы, вероятно, хотите сделать что-то более похожее на:

#include <iostream>
#include <string>
#include <vector>

float check_q(const std::vector<std::string>& args)
{
if(args[1] == "-q")
{
return ::atof(args[2].c_str());
}
else
{
return 0.0f;   // or some other default
}
}

int main(int argc, char *argv[])
{
const std::vector<std::string> args(argv, argv+argc);

if(args.size() >= 3) // argv[0] is usually the name of the executable
{
std::cout << check_q(argv) << std::endl;
}
else
{
std::cout << "not enough args" << std::endl;
}
}

Как только вы станете немного опытнее, вам захочется использовать такую ​​библиотеку, как GNU getopt или же повышение :: program_options.

1

В этом коде есть много вещей, которые не имеют большого смысла или не являются безопасными или элегантными, и я не уверен, чего вы пытаетесь достичь с помощью проверки аргументов 1,3, 5 и 7, но вот как минимум одна проблема:

qa в main никогда не будет обновлен, потому что вы не назначаете возвращаемое значение check_q к этому. Заявление должно быть:

float qa = 0;
qa = check_q(argv);

Или действительно, просто:

float qa = check_q(argv);
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector