Передача строки std::в качестве входных данных в getopt()

#c #argv #getopt

Вопрос:

У меня есть программа, которая в основном выглядит так:

 #include <iostream>
#include <unistd.h> // getopt
#include <vector>
#include <string>
#include <list>
#include <sstream>

using namespace std;

//a parameter structure to store parameters provided through console
typedef struct pairwise_param {
    double alpha;
    double beta;
} param;

//parse the parameter values
void param_getopt(param *pm, int argc, char **argv) {
    int opt;

    while((opt = getopt(argc, argv, "a:b:")) != -1) {
        switch(opt) {
        case 'a':
            pm->alpha  = atof(optarg);
            break;

        case 'b':
            pm->beta   = atof(optarg);
            break;
        }
    }
}

int main(int argc, char* argv[]) {
    //initialize param structure
    param pm;

    //pass command line arguments to param
    param_getopt(amp;pm, argc, argv);

    //do something to the parameters
    std::cout << "Alpha: " << pm.alpha  << std::endl;
    std::cout << "Beta: " << pm.beta  << std::endl;


    return(0);
}
 

Создав файл заголовка и изменив основную функцию на другое имя, например int main(int argc, char* argv[]) -> int maincomp(int argc, char* argv[]) , я хочу вызвать новую функцию maincomp() из другой программы, но вместо передачи аргументов командной строки я хочу передать аргументы через a std::string .

Я думал, что смогу сделать что-то подобное, но, похоже, у меня есть некоторые проблемы с getopt() этим, я не совсем уверен, почему. В настоящее время все, что записывается в консоль с помощью, например std::cout , после getopt() вызова, не будет отображаться. Похоже, что то, что передается в getopt() настоящее время, неправильно преобразовано в тип. Поэтому мой вопрос заключается в том, как один тип должен приводить a std::string в соответствие с char * const argv[] требованиями ввода getopt(int argc, char * const argv[]) ?

 int main(int argc, char* argv[]) {
    //create string and pass it to maincomp
    std::string cmd = "-a2.3 -b3.2";
    std::istringstream ss(cmd);
    std::string arg;
    std::list<std::string> ls;
    std::vector<char*> newargv;

    while (ss >> arg) {
        ls.push_back(arg);
        newargv.push_back(const_cast<char*>(ls.back().c_str()));
    }

    newargv.push_back(0);

    int out = maincomp(newargv.size(), amp;newargv[0]);

    return(out);
}
 

Весь код:
https://onlinegdb.com/tjMC-LwiP

Комментарии:

1. почему ты пометил С? Что такое «некоторые проблемы» ?

2. Извините за расплывчатость. Код компилируется, но когда он переходит во getopt() что-либо напечатанное после этого, вывод буфера потока с std::cout не отображается. Указывая, что getopt() это, скорее всего, проблема. Помеченный C из-за getopt изначально является функцией библиотеки C в стиле POSIX

Ответ №1:

Использование wordsexp.h решило проблему, правильно проанализировав строку для getopt() .

По существу:

 //create string and pass it to maincomp    
std::string cmd = "-a2.3 -b3.2";

//convert string with wordexp
wordexp_t newargv;
newargv.we_offs = 1;
wordexp(cmd.c_str(), amp;newargv, WRDE_DOOFFS);
//create a new argc
int newargc = newargv.we_wordc   newargv.we_offs;
    
//pass to maincomp function
int out = maincomp(newargc, newargv.we_wordv);
 

Полный код:

 #include <iostream>
#include <unistd.h> // getopt
#include <vector>
#include <string>
#include <wordexp.h>


typedef struct pairwise_param {
  double alpha; double beta;
} param;

void param_getopt(param *pm, int argc, char **argv){
    int opt;
    while((opt=getopt(argc,argv,"a:b:"))!=-1){
        switch(opt){
            case 'a': pm->alpha  = atof(optarg);              break;
            case 'b': pm->beta   = atof(optarg);              break;
        }
    }
}

int maincomp(int argc, char* argv[]){
  //initialize param structure
  param pm;

  //pass command line arguments to param
  param_getopt(amp;pm, argc, argv);
  
  std::cout << "Alpha: " << pm.alpha  << std::endl;
  std::cout << "Beta: " << pm.beta  << std::endl;


  return(0);
}

int main(int argc, char* argv[]) {
    //create string and pass it to maincomp    
    std::string cmd = "-a2.3 -b3.2";

    //convert string with wordexp
    wordexp_t newargv;
    newargv.we_offs = 1;
    wordexp(cmd.c_str(), amp;newargv, WRDE_DOOFFS);
    int newargc = newargv.we_wordc newargv.we_offs;

    //pass to maincomp function
    int out = maincomp(newargc, newargv.we_wordv);

    return(out);
}
 

Производит ожидаемый результат:

 Alpha: 2.3
Beta: 3.2