командная строка getopt получает значения c ++

0

Как вы получаете значения флагов в getopt, я пробовал использовать его в googling, но все, что у меня есть, это о том, как переключать случаи и устанавливать флаги. Я получил код ниже и то, что я пытаюсь сделать, это иметь три флага: -a, -b, -c, но передаются только два флага, например ./filename -a somevalue -c anothervalue или ./filename -b somevalue -c anothervalue любая помощь?

int main(int argc, char *argv[])
{
   int flagA = 0;
   int flagB = 0;

   while (1) {
    char c;

    c = getopt (argc, argv, "abc:");
    if (c == -1) {
        break;
    }
    switch (c) {
    case 'a':
        flagA = 1;
         //cout<<optarg<<endl; //I tried printing the value but it only prints the second  flag value
        break;
    case 'b':
        flagB = 1;
        cout<<optarg<<endl;
        break;
    case 'c':
        cout<<optarg<<endl;
        break;
   case '?':
    default:
       cout<<"Usage: %s [-a] [-b <something>].\n", argv[0]<<endl;
    }
   if(flagA > 0){
    //do something using the values of flagA and flagC 
   }
   else if(flagB > 0){
      //do something using the values of flagB and flagC

   }
 }
 return 0;
 }
Теги:

2 ответа

0

Если вы намерены использовать optarg с флагом, флаг должен иметь : после него в строке опций.

        c = getopt(argc, argv, "a:b:c:");

Вывод вывода использования не должен компилироваться для вас. Кроме того, вы пытаетесь смешивать спецификаторы формата стиля C в выходной поток C++, что неверно.

            cout << "Usage: " << argv[0] << " [-a] [-b <something>].\n";
  • 0
    Спасибо за помощь, но когда я запускаю ./filename -a 5 -c "некоторый текст", он печатает только 5.
  • 0
    правильно, но все, что я хочу, это иметь значения флагов, которые не отображают оба значения. cout<<optarg<<endl; это все, что я делаю так же, как у меня в коде.
Показать ещё 1 комментарий
0

Существует несколько проблем с кодом, но ключевой заключается в вызове getopt(). У вас есть строка управления опцией "abc:", что означает, что ни -a ни -b имеют опции.

Предполагая, что вы используете стандартную версию POSIX getopt() а не GNU getopt(), тогда при запуске:

./filename -a somevalue -c anothervalue
./filename -b somevalue -c anothervalue

somevalue после первого флага означает, что параметры завершены, а остальные аргументы являются аргументами без опций. GNU getopt(), в отсутствие переменной POSIXLY_CORRECT -c anothervalue список аргументов, чтобы еще -c anothervalue распознано (и аргументы переставляются таким образом, что somevalue заканчивается в конце).

Ваш код будет лучше написан:

#define _XOPEN_SOURCE 600 
#include <iostream>
#include <unistd.h>
using namespace std;

int main(int argc, char *argv[])
{
    int flagA = 0;
    int flagB = 0;
    int opt;
    char *c_opt = 0;

    while ((opt = getopt(argc, argv, "abc:")) != -1)
    {
        switch (opt)
        {
        case 'a':
            flagA = 1;
            cout << "A: " << flagA << "\n";
            break;
        case 'b':
            flagB = 1;
            cout << "B: " << flagB << "\n";
            break;
        case 'c':
            c_opt = optarg;
            cout << "C: " << c_opt << "\n";
            break;
        default:
            cerr << "Usage: " << argv[0] << " [-a] [-b] [-c <something>]\n";
            return -1;
        }
    }

    if (flagA)
    {
        // do something using the values of flagA and c_opt (if set)
    }
    else if (flagB)
    {
        // do something using the values of flagB and c_opt (if set)
    }
    else if (c_opt)
    {
        // do something using just c_opt (neither flagA nor flagB is set)
    }
    else
    {
        // do something if no options are specified (report error?)
    }

    for (int i = optind; i < argc; i++)
        cout << "File: " << i << ": " << argv[i] << "\n";
    return 0;
}

Код выше (с поправками) компилируется с GCC 4.9.1 в Mac OS X 10.10 (Yosemite):

g++ -O3 -g -std=c++11 -Wall -Wextra -Werror opt.cpp -o opt

BSD-ish getopt() рядом с стандартом POSIX, поэтому я получаю:

$ ./opt -a 5 -c something
A: 1
File: 2: 5
File: 3: -c
File: 4: something
$

florw.wat прокомментировал:

Я хочу, чтобы -a и -b принимали аргумент. То, что я пытаюсь сделать, состоит в том, что у меня есть две функции, которые принимают два аргумента, поэтому, если установлен -a, я хотел бы вызвать функцию a else, если -b затем вызывает функцию b. Мне нужны два значения для вызова функций.

Учитывая это разъяснение, код может выглядеть так:

#define _XOPEN_SOURCE 600
#include <cstdlib>
#include <iostream>
#include <unistd.h>
using namespace std;

static void usage(const char *arg0)
{
    cerr << "Usage: " << arg0 << " [-a filename | -b filename] -c <something>\n";
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
    char *a_opt = 0;
    char *b_opt = 0;
    char *c_opt = 0;
    int opt;

    while ((opt = getopt(argc, argv, "a:b:c:")) != -1)
    {
        switch (opt)
        {
        case 'a':
            a_opt = optarg;
            cout << "A: " << a_opt << "\n";
            break;
        case 'b':
            b_opt = optarg;
            cout << "B: " << b_opt << "\n";
            break;
        case 'c':
            c_opt = optarg;
            cout << "C: " << c_opt << "\n";
            break;
        default:
            cerr << "Unknown option: " << optopt << "\n";
            usage(argv[0]);
            break;
        }
    }

    if (optind != argc || c_opt == 0 || (a_opt && b_opt) || (a_opt == 0 && b_opt == 0))
        usage(argv[0]);
    else if (a_opt)
        cout << "A&C: " << a_opt << " " << c_opt << "\n";
    else
        cout << "B&C: " << b_opt << " " << c_opt << "\n";

    return 0;
}

Пример прогона:

$ ./opt -a option -c something
A: option
C: something
A&C: option something
$
  • 0
    Это не работает, когда я делаю ./filename -a 5 -c "sometext" я получаю Usage: ./project [-a] [-b] [-c <something>]
  • 0
    также я нахожусь на codeblocks .. Ubuntu, я не уверен, как я знаю, какой из них является стандартом.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню