2016-10-05 13 views
1

Привет очень новичка вопрос, но я просто не могу понять:создать ARGC ARGV в коде

У меня есть функция под названием бар

class foo 
{ 
    public: 
     bool bar(int argc, char** argv); 
} 

ARGV, как предполагается, содержат

"--dir" and "/some_path/" 

Как создать argv и argc, чтобы я мог передать их в bar()? Я пробовал много способов, но я просто не могу правильно преобразовать указатель и тип.

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

Благодарим вас за вход!

+0

создать ?? нет! вы можете передавать аргументы в свою программу через argv. argc - количество переданных параметров. argv может содержать любые значения, пути ... – Raindrop7

+0

@ Raindrop7, иногда вам приходится создавать argc и argv внутри программы. Например, если вы хотите использовать тест блока boost, вы в конечном итоге назовете main. И на android (если вы хотите запускать тесты на устройстве), вы должны вызвать его самостоятельно, и вам нужно сформировать аргументы для него. –

ответ

5

Мой любимый способ, как это:

std::vector<std::string> arguments = {"--dir", "/some_path"}; 

std::vector<char*> argv; 
for (const auto& arg : arguments) 
    argv.push_back((char*)arg.data()); 
argv.push_back(nullptr); 

f.bar(argv.size() - 1, argv.data()); 

Обратите внимание, что если аргументы статичны и не меняются, то это немного перебор. Но этот подход имеет преимущество в отношении соответствия RAII. Он управляет памятью для вас и удаляет объекты в нужный момент. Поэтому, если список аргументов является динамическим, то это самый чистый способ.

Кроме того, этот код технически является UB, если f.bar изменяет данные в массиве argv. Обычно это не так.

+1

неявное преобразование из 'const char *' в 'char *' снова. – Slava

+0

Я сделал преобразование явным и добавил уведомление о UB. –

+1

Для C++ 11 вы можете использовать ссылку lvalue и '& arg [0]' без каких-либо бросков. Во всяком случае, я предпочел бы 'const_cast <>', а не C-стиль. – Slava

0

Предполагая, что вы хотите ARGC и ARGV в том же формате, которые передаются main, вы можете назвать это так:

foo f; 
char *args[] = { 
    (char*)"--dir", 
    (char*)"/some_path/", 
    NULL 
}; 
f.bar(2, args); 

(примечание: это предполагает bar не будет изменять строки аргументов - в которой случае следует изменить тип аргумента в const char ** вместо char **)

+2

Преобразование из 'const char *' в 'char *' является незаконным в C++ – Slava

+0

segfault! нет распределения для argv – Raindrop7

+0

@Slava Нет, это не так. Преобразование, если оно сделано явным приложением, действует во всех версиях C++. До C++ 11 преобразование также может выполняться неявно, но только для строковых литералов (которые есть в этом ответе). Недопустимы только попытки изменить строку с указателем. – hvd

0

использование строки класс слишком мощный:

#include <iostream> 
#include <string> 

class foo 
{ 
    public: 
     void bar(int argc, std::string* argv); 
}; 

void foo::bar(int argc, std::string* argv) 
{ 
    //do somwthing 
    for(int i(0); i < argc; i++) 
     std::cout << "argv[" << i << "]: " << argv[i] << std::endl; 
} 


int main() 
{ 


    int argc; 
    std::cout << "Enter number of parameters: "; 
    std::cin >> argc; 
    std::cout << std::endl; 
    std::cin.ignore(1, '\n'); 

    std::string* sArgv = new std::string[argc]; 

    for(int i(0); i < argc; i++) 
    { 
     std::cout << "argv[" << i << "]: "; 
     std::getline(std::cin, sArgv[i]); 
     std::cout << std::endl; 
     std::cin.ignore(1, '\n'); 
    } 


    foo theFoo; 
    theFoo.bar(argc, sArgv); 

    delete[] sArgv; 
    sArgv = NULL; 

    std::cout << std::endl; 

    return 0; 
}