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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

2653閲覧

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

hanayamaKaoru

総合スコア36

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/11/24 19:12

編集2016/11/25 11:52

###前提・実現したいこと
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>

java

1import org.kohsuke.args4j.Argument; 2import org.kohsuke.args4j.Option; 3import org.kohsuke.args4j.spi.StringArrayOptionHandler; 4 5public class Shell { 6 7 8 @Option(name="-v", metaVar="x", handler=StringArrayOptionHandler.class) 9 static String[] vcm; 10 11 12 13}

java

1import org.kohsuke.args4j.CmdLineException; 2import org.kohsuke.args4j.CmdLineParser; 3 4public class Main { 5 public static void main(String[] args){ 6 Shell shell = new Shell(); 7 8 CmdLineParser parser = new CmdLineParser(shell); 9 try { 10 parser.parseArgument(args); 11 } catch (CmdLineException e) { 12 e.printStackTrace(); 13 return; 14 } 15 Matrix2D vcm = new Matrix2D(shell.vcm); 16 17 } 18 19} 20

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

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

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

  • Mac OSX 10.9, JDK1.7

Main.java

java

1import org.kohsuke.args4j.CmdLineException; 2import org.kohsuke.args4j.CmdLineParser; 3 4public class Main { 5 public static void main(String[] args) { 6 Shell shell = new Shell(); 7 8 CmdLineParser parser = new CmdLineParser(shell); 9 try { 10 parser.parseArgument(args); 11 } catch (CmdLineException e) { 12 e.printStackTrace(); 13 return; 14 } 15 16 for (String s : shell.vcm) { 17 System.out.println(s); 18 } 19 20 } 21 22}

Shell.java

java

1import org.kohsuke.args4j.Option; 2 3public class Shell { 4 5 @Option(name = "-v", metaVar = "x", handler = WellBehavedStringArrayOptionHandler.class) 6 static String[] vcm; 7 8}

WellBehavedStringArrayOptionHandler.java

java

1import org.kohsuke.args4j.CmdLineException; 2import org.kohsuke.args4j.CmdLineParser; 3import org.kohsuke.args4j.OptionDef; 4import org.kohsuke.args4j.spi.Messages; 5import org.kohsuke.args4j.spi.OptionHandler; 6import org.kohsuke.args4j.spi.Parameters; 7import org.kohsuke.args4j.spi.Setter; 8 9public class WellBehavedStringArrayOptionHandler extends OptionHandler<String> { 10 public WellBehavedStringArrayOptionHandler(CmdLineParser parser, OptionDef option, 11 Setter<String> setter) { 12 super(parser, option, setter); 13 } 14 15 @Override 16 public String getDefaultMetaVariable() { 17 return Messages.DEFAULT_META_STRING_ARRAY_OPTION_HANDLER.format(); 18 } 19 20 @Override 21 public int parseArguments(Parameters params) throws CmdLineException { 22 int counter; 23 for (counter = 0; counter < params.size(); counter++) { 24 String param = params.getParameter(counter); 25 if (param.startsWith("-")) { 26 break; 27 } 28 setter.addValue(param); 29 } 30 return counter; 31 } 32}

実行時引数

-v "2 1" 1

実行結果

2 1 1

投稿2016/11/25 08:05

編集2016/11/25 08:08
KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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: 文字列の置換

投稿2016/11/25 04:19

編集2016/11/25 04:25
BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

投稿2016/11/25 02:58

himakuma

総合スコア952

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問