質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

StringではなくString[]として受け取りたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,123

score 36

前提・実現したいこと

args4jのStringArrayOptionHandlerを用いてコマンドライン引数を受け取っているのですが思った挙動を示しません

コマンドラインへの入力
"2 1" 1
直接、main関数に入力した場合
args[0] = "2 1"
args[1] = "1"

コマンドラインへの入力
-v "2 1" 1
StringArrayOptionHandlerで処理した場合
vcm[0] = "2"
vcm[1] = "1"
vcm[2] = "1"

直接、main関数に入力した場合のように空白を処理しない挙動を望んでいます

結論

handlerの空白を処理するという挙動は仕様なので実行引数の入力を工夫したところで解決はできない
今回は条件に合うhandlerOptionHandlerは既に作成されていたのでそのhandlerを用いれば良い
しかし、自分の望むぱparseの挙動を示すhandlerがない場合
handlerを@Overrideして自分で作成する必要がある

回避策1:
parser.parseArgument(args);を実行する前にargsの要素の空白を別の文字で置き換えを行う
回避策2:
main関数への入力を空白の代わりの文字で行う

発生している問題・エラーメッセージ

空白が処理されてしまいString[]の要素1つに一文字しか入らない

該当のソースコード

mavenを使用
<!-- https://mvnrepository.com/artifact/args4j/args4j -->
<dependency>
<groupId>args4j</groupId>
<artifactId>args4j</artifactId>
<version>2.33</version>
</dependency>

import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.spi.StringArrayOptionHandler;

public class Shell {


      @Option(name="-v", metaVar="x", handler=StringArrayOptionHandler.class)
        static String[] vcm;



}
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;

public class Main {
    public static void main(String[] args){
        Shell shell = new Shell();

        CmdLineParser parser = new CmdLineParser(shell);
        try {
            parser.parseArgument(args);
        } catch (CmdLineException e) {
            e.printStackTrace();
            return;
        }
        Matrix2D vcm = new Matrix2D(shell.vcm);

    }

}

試したこと

コマンドラインの引数を""や''で囲んでみましたが空白は処理されてしまいました

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

StackOverflowにも同様の質問があり、その回答によると、StringArrayOptionHandler では意図する動作を実現できないようです。
http://stackoverflow.com/a/36540388/6299234

で、私の手元の環境(*)では、使用するオプションハンドラーを その回答で提示されているクラスに切り替えると、うまく動作しました。

  • Mac OSX 10.9, JDK1.7

Main.java

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;

public class Main {
    public static void main(String[] args) {
        Shell shell = new Shell();

        CmdLineParser parser = new CmdLineParser(shell);
        try {
            parser.parseArgument(args);
        } catch (CmdLineException e) {
            e.printStackTrace();
            return;
        }

        for (String s : shell.vcm) {
            System.out.println(s);
        }

    }

}


Shell.java

import org.kohsuke.args4j.Option;

public class Shell {

    @Option(name = "-v", metaVar = "x", handler = WellBehavedStringArrayOptionHandler.class)
    static String[] vcm;

}


WellBehavedStringArrayOptionHandler.java

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.Messages;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;

public class WellBehavedStringArrayOptionHandler extends OptionHandler<String> {
    public WellBehavedStringArrayOptionHandler(CmdLineParser parser, OptionDef option,
            Setter<String> setter) {
        super(parser, option, setter);
    }

    @Override
    public String getDefaultMetaVariable() {
        return Messages.DEFAULT_META_STRING_ARRAY_OPTION_HANDLER.format();
    }

    @Override
    public int parseArguments(Parameters params) throws CmdLineException {
        int counter;
        for (counter = 0; counter < params.size(); counter++) {
            String param = params.getParameter(counter);
            if (param.startsWith("-")) {
                break;
            }
            setter.addValue(param);
        }
        return counter;
    }
}


実行時引数

-v "2 1" 1


実行結果

2 1
1

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

「-v "2 1" -v 1」と入力するとどうでしょうか?
「-v」以降が1つの引数として扱われていると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

根本的な解決にはなりませんが、回避方法なら。

方法1:
複数の文字列を 一つの文字列とみなす場合、スペース ( 空白 ) ではなく 別の文字で区切る。

例:
( "," で区切るとして。 )

java Test "223,11" a

=> 223,11 & a

これをどうしても半角スペースにしたいのであれば、
mainメソッド内( 等 ) で、

  1. 文字列として取得
  2. String の "指定文字(列) を指定文字列に変換するメソッドで"," から 半角スペースに変換
  3. なんらかの処理

みたいに。

たとえば、

avcm[0] に入っているとして。

// カンマを 半角スペースに変更
avcm[0].replaceAll( ",", " " );

という感じで、プログラムから判断し変換する。

方法2:
うまくいく方 ( mainメソッドの引数の方 ) を使用する。
どうしても、使うクラスやメソッドの引数等でStringArrayOptionHandler(?) が求められるなら、
mainメソッドの引数 -> StringArrayOptionHandlerに変換(?) とする。

ヒント:
Java: 文字列の置換

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る