аргументы в стиле getopts для скомпилированных программ matlab - PullRequest
2 голосов
/ 09 мая 2019

Помимо использования оболочки, есть ли способ использовать аргументы в стиле getopts (например, -v или -n 3 или --some_parameter=7) в программах Matlab, скомпилированных с использованием mcc?

Ответы [ 2 ]

3 голосов
/ 10 мая 2019

Если вы хотите создать getopt -подобную функциональность командной строки для ваших программ MATLAB (скомпилированные или нет), то используйте объект inputParser (обычно лучший подход к обработке ввода) не будет вашим лучшим вариантом. Функциональность inputParser хорошо ориентирована на аргументы функции, которые следуют за определенным порядком (то есть позиционированием в списке аргументов) и которые следуют формату «пара параметр / значение». Типичная функциональность стиля getopt включает списки опций, которые не обязаны следовать определенному порядку и имеют оба формата «только опция» (например, -v) или «опция с аргументом» (например, -n 3 или --some_parameter=7).

Скорее всего, вам понадобится добавить свои собственные процедуры анализа ввода в самом начале вашей скомпилированной программы. Как уже упоминалось здесь и здесь , когда вы используете командный синтаксис для вызова вашей программы, все входные данные передаются в виде последовательности символьных векторов. Если вы определяете функцию с помощью списка переменных входных аргументов , например:

function getopt_example(varargin)

Затем вызывается функция следующим образом:

getopt_example -v -n 3 --some_parameter=7

приведет к varargin, имеющему следующее содержимое:

  1×4 cell array

    {'-v'}    {'-n'}    {'3'}    {'--some_parameter=7'}

Затем необходимо будет выполнить итерацию по этому массиву ячеек, проанализировав параметры и соответственно установив / сохранив аргументы (после преобразования их из символьных векторов в числовые значения по мере необходимости). Есть много способов реализовать это, в зависимости от того, какие форматы опций вы хотите разрешить. Вот пример одного из способов разбора типа примеров аргументов, которые вы упомянули выше:

function getopt_example(varargin)

  % Define opts as {'name', has an argument, default value}:
  opts = {'v', false, false; ...              % No argument, default unset
          'n', true, 1; ...                   % double argument, default 1
          'some_parameter', true, uint8(0)};  % uint8 argument, default 0
  args = {};  % Captures any other arguments

  % Parse input argument list:
  inputIndex = 1;
  while (inputIndex <= nargin)

    opt = varargin{inputIndex};
    if strcmp(opt(1), '-') || strcmp(opt(1:2), '--')  % A command-line option

      % Get option and argument strings:
      opt = strip(opt, 'left', '-');
      [opt, arg] = strtok(opt, '=');
      [isOpt, optIndex] = ismember(opt, opts(:, 1));
      assert(isOpt, 'Invalid input option!');

      if opts{optIndex, 2}  % Has an argument

        if isempty(arg)  % Argument not included with '='
          assert(inputIndex < nargin, 'Missing input argument!');
          arg = varargin{inputIndex+1};
          inputIndex = inputIndex+2;
        else  % Argument included with '='
          arg = arg(2:end);
          assert(~isempty(arg), 'Missing input argument!');
          inputIndex = inputIndex+1;
        end

        % Convert argument to appropriate type:
        argType = class(opts{optIndex, 3});
        if ~strcmp(argType, 'char')
          arg = cast(str2double(arg), argType);
          assert(~isnan(arg), 'Invalid input option format!');
        end
        opts{optIndex, 3} = arg;

      else  % Has no argument

        opts{optIndex, 3} = true;
        inputIndex = inputIndex+1;

      end

    else  % A command-line argument

      args = [args {opt}];
      inputIndex = inputIndex+1;

    end

  end

  % Display results:
  disp(opts(:, [1 3]));
  disp(args);

end

В массиве ячеек opts изначально хранятся возможные параметры, если они имеют связанный аргумент, и значение по умолчанию. После анализа входных аргументов значения по умолчанию будут перезаписаны любыми значениями, переданными функции. Массив ячеек args захватывает любые аргументы, которые не соответствуют ни одному из параметров. Вот некоторые примеры входных данных и результатов:

>> getopt_example -v -n 3 --some_parameter=7  % Sample inputs
    'v'                 [1]
    'n'                 [3]
    'some_parameter'    [7]

>> getopt_example -n 3 --some_parameter=7  % Omit -v option
    'v'                 [0]
    'n'                 [3]
    'some_parameter'    [7]

>> getopt_example -v -n --some_parameter=7  % Omit argument for -n option
Error using getopt_example (line 38)
Invalid input option format!

>> getopt_example -v -b --some_parameter=7  % Pass invalid -b option
Error using getopt_example (line 20)
Invalid input option!

>> getopt_example -v -n 3 --some_parameter=7 a1  % Pass additional argument a1
    'v'                 [1]
    'n'                 [3]
    'some_parameter'    [7]

    'a1'
1 голос
/ 09 мая 2019

Похоже, вы ищете объект inputParser .

отредактировано на основе комментария об ответе только для ссылки.

Вот пример использования функции, которая имеет 2 обязательных входа и 2 необязательных параметра:

function hObj = dasImagePrototype(hAx, dasStruct, varargin)

% ...

defaultDepthUnit = getpref('HOTB', 'units_unitSystem', 1);

p = inputParser;
p.addRequired('hAx', @(x) isa(x, 'matlab.graphics.axis.Axes'))
p.addRequired('dasStruct', @(x) isstruct(x) && isfield(x,'psd'))
p.addParameter('depthUnit', defaultDepthUnit, @(x) ismember(x,1:2))
p.addParameter('whichFbe', 1, @(x) floor(x)==x && x>0)
p.parse(hAx, dasStruct, varargin{:})

% access hAx & dasStruct directly since they're `Required` inputs
% but we still pass them to the input parser anyways to validate
hObj.hAx = hAx;
hObj.dasStruct = dasStruct; 

% note that since depthUnit & whichFbe are `Parameter` and not 
% `Required` inputs, we need to access them from the p object
hObj.depthUnit = p.Results.depthUnit;
hObj.whichFbe = p.Results.whichFbe;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...