回答編集履歴

5

inM\.csvファイルが空の場合のプログラム終了方法について追記しました

2016/03/21 12:43

投稿

tatsuya6502
tatsuya6502

スコア2035

test CHANGED
@@ -271,3 +271,131 @@
271
271
  切り捨てと、四捨五入では、<<< >>> でマークした所に違いがありますが、どちらも期待している答えとは違いますね。仕様について、確認してもらえないでしょうか?
272
272
 
273
273
 
274
+
275
+ ---
276
+
277
+
278
+
279
+ **2016年3月21日 追記**
280
+
281
+
282
+
283
+ > ②inM.csvファイルが空の場合エラー表示して通常終了したい
284
+
285
+ > のですが次の処理に進んでしまいます。
286
+
287
+
288
+
289
+ 回答が遅くなりました。
290
+
291
+
292
+
293
+ いまのプログラムは以下のような構造になっていますので、
294
+
295
+
296
+
297
+ ```
298
+
299
+ public static void main(String[] args) {
300
+
301
+
302
+
303
+ boolean emptyflgM = true; //inM判定マスタファイル空判定フラグ
304
+
305
+
306
+
307
+ // ... 省略 ...
308
+
309
+
310
+
311
+ fileError1:
312
+
313
+ try {
314
+
315
+ while ((stM = brM.readLine()) != null) {
316
+
317
+ emptyflgC = false;
318
+
319
+
320
+
321
+ // ... inM ファイルの読み込み
322
+
323
+ }
324
+
325
+
326
+
327
+ if (emptyflgM) {
328
+
329
+ System.err.println("inM.csvファイルは空です。");
330
+
331
+ break fileError1;
332
+
333
+ }
334
+
335
+
336
+
337
+ } catch(IOException e){
338
+
339
+ // ...
340
+
341
+ } finally {
342
+
343
+ // ...
344
+
345
+ }//finally
346
+
347
+
348
+
349
+ // ... 次の処理
350
+
351
+
352
+
353
+ }
354
+
355
+ ```
356
+
357
+
358
+
359
+ 「inM.csvファイルは空です」を表示して、try 文から break しても、たしかに、次の処理と書かれた部分は実行されてしまいます。
360
+
361
+
362
+
363
+ エラー表示後、プログラムを正常終了させたいということなので、`System.exit(0)` を呼ぶのが良いと思います。`break flieError` と書く代わりに、`System.exit(0)` と書くと、(main メソッドを最後まで実行した時と同じように)Java仮想マシンの終了処理が行われ、プログラムが終了します。
364
+
365
+
366
+
367
+ - [System.exit(int) の解説](http://docs.oracle.com/javase/jp/8/docs/api/java/lang/System.html#exit-int-)
368
+
369
+
370
+
371
+ 引数の `0` は、正常終了を表します。ただ、このように入力ファイルに不備がある場合は、`0` 以外の値を返すことで、異常終了を表すのが一般的です。
372
+
373
+
374
+
375
+ 今回のように、`try` 〜 `catch` 〜 `finally` の中から `System.exit(0)` を呼んだ場合、`finally` の部分もちゃんと実行されます。また、もっと大きなプログラムを書いていて、何らかの終了処理を行いたい時は、shutdown hook というものを設定することで、`System.exit(int)` を呼んだ時に、その処理を実行することができます。
376
+
377
+
378
+
379
+ なお、今回のプログラムだと、`System.exit(0)` ではなく、単に `return` と書いて、main メソッドから早期に抜け出す方法も使えます。ただ、この方法は応用がきかないので、おすすめはしません。今後、Java を学んでいくと、メソッドを分割するとか、クラスを分けるなどといった、プログラムを構造化することが必ず必要になります。そういう構造になってくると、inMファイルの読み込みも、main とは別のメソッドで行われるようになり、単にそのメソッドから `return` するだけでは、Java仮想マシンを終了させることができません。
380
+
381
+
382
+
383
+ さらに、今後学習していくなかで、エラー処理の方法についても調べてみてください。大きくわけて、2つの方法があります。
384
+
385
+
386
+
387
+ 1. エラーをメソッドからの戻り値で表す。例えば、Result といった名前のクラスを作り、メソッドが返す値を Resultオブジェクトにする。メソッドがエラーなく終了した時は、Resultオブジェクトに値(例:inM.csvファイルの内容)を格納して返す。エラーが起こった時は、Resultオブジェクトにエラーの内容を示す値を格納して返す。
388
+
389
+
390
+
391
+ 2. エラーを例外(Exception) で表す。例えば、`EmptyFileException` というような名前の例外クラスを作り、エラーが起こった時は、`throw new EmptyFileException()` というようにして例外を投げる。
392
+
393
+
394
+
395
+ Java は少し古い言語で、1の方法で呼び出し側(値を受け取った側)の処理が簡潔に書けないという問題があります。2は Java でエラー処理を行う中心的なやりかたですが、あまり例外を増やすと、プログラムの流れが分かりにくくなるという問題があります。
396
+
397
+
398
+
399
+ Java に慣れたら、1のような処理を簡潔に書ける、最近の言語もぜひ並行して学んでください。たとえば、Java で学んだ知識を活かせる、Scala という言語がおすすめです。
400
+
401
+

4

誤字を修正しました

2016/03/21 12:43

投稿

tatsuya6502
tatsuya6502

スコア2035

test CHANGED
@@ -150,7 +150,7 @@
150
150
 
151
151
 
152
152
 
153
- でも、これを直して試してみたのですが、期待した答えにならないかったですねぇ。うーん、仕様か期待している答えのどちらかが間違っているような気がします。
153
+ でも、これを直して試してみたのですが、期待した答えにならないかったですねぇ。うーん、仕様か、あるいは、期待している答えのどちらかが間違っているような気がします。
154
154
 
155
155
 
156
156
 
@@ -178,7 +178,7 @@
178
178
 
179
179
  int intMIndex = intEven ? 1 : 0;
180
180
 
181
- String intOut = masterM[intMIndex][1].equals("yes") ? "outA" : "outB";
181
+ String intOut = masterM[intMIndex][1].equals("") ? "outA" : "outB";
182
182
 
183
183
 
184
184
 
@@ -200,7 +200,7 @@
200
200
 
201
201
  int doubleMIndex = doubleEven ? 1 : 0;
202
202
 
203
- String doubleOut = masterM[doubleMIndex][1].equals("yes") ? "outA" : "outB";
203
+ String doubleOut = masterM[doubleMIndex][1].equals("") ? "outA" : "outB";
204
204
 
205
205
 
206
206
 

3

誤字を修正しました

2016/03/18 12:07

投稿

tatsuya6502
tatsuya6502

スコア2035

test CHANGED
@@ -82,7 +82,7 @@
82
82
 
83
83
 
84
84
 
85
- のところですが、`numC[i]` とすると、長さ2の String配列がってきてしまうので、たしかに型の不一致となります。以下のように、String配列の各要素を一つずつチェックしてください。
85
+ のところですが、`numC[i]` とすると、長さ2の String配列がってくるので、たしかに型の不一致となります。以下のように、String配列の各要素を一つずつチェックしてください。
86
86
 
87
87
 
88
88
 

2

誤字を修正しました

2016/03/18 12:04

投稿

tatsuya6502
tatsuya6502

スコア2035

test CHANGED
@@ -76,7 +76,7 @@
76
76
 
77
77
  ```java
78
78
 
79
- if (isHanNum(numC[i])) {
79
+ if (isHanNum(numC[i]) == false) {
80
80
 
81
81
  ```
82
82
 

1

質問①と②について追記しました

2016/03/18 12:03

投稿

tatsuya6502
tatsuya6502

スコア2035

test CHANGED
@@ -47,3 +47,227 @@
47
47
 
48
48
 
49
49
  プログラムの内容を詳しく見てないので、他にも間違いがあるかもしれませんが、とりあえず、いま出ているエラーについて気づいたことは、これで全部です。
50
+
51
+
52
+
53
+ ---
54
+
55
+
56
+
57
+ ---
58
+
59
+ **2016年3月18日 質問①と②について追記**
60
+
61
+
62
+
63
+ ③は説明が長くなりそうなので、後で(明日?)書きます。
64
+
65
+ 取り急ぎ、①と②について回答しますね。
66
+
67
+
68
+
69
+ > ①数値化出来るかどうかをisHanNum(String s)メソッドを使用
70
+
71
+ > したいのですが、配列の要素だと型の不一致でコンパイル
72
+
73
+ > 出来ません。
74
+
75
+
76
+
77
+ ```java
78
+
79
+ if (isHanNum(numC[i])) {
80
+
81
+ ```
82
+
83
+
84
+
85
+ のところですが、`numC[i]` とすると、長さ2の String配列が帰ってきてしまうので、たしかに型の不一致となります。以下のように、String配列の各要素を一つずつチェックしてください。
86
+
87
+
88
+
89
+ ```java
90
+
91
+ if (!isHanNum(numC[i][0]) || !isHanNum(numC[i][1])) {
92
+
93
+ ```
94
+
95
+
96
+
97
+ ---
98
+
99
+ > ②除算した結果を偶数か奇数で判断したいのですが。int同士だと
100
+
101
+ > 小数点以下切り捨てなので、すべてが偶数になってしまいます。
102
+
103
+
104
+
105
+ たしかに小数点以下切り捨てですが、でも、偶数だけでなく、奇数になることもあります。
106
+
107
+
108
+
109
+ まず、以下のところに間違いがあることに気づきました。
110
+
111
+
112
+
113
+ ```java
114
+
115
+ if (quotient % 2 == 0) { // 偶数かどうかを確認
116
+
117
+ if (masterM[1][0].equals("○")) {
118
+
119
+ // ...省略...
120
+
121
+
122
+
123
+ } else {
124
+
125
+ if (masterM[0][0].equals("○")) {
126
+
127
+ ```
128
+
129
+
130
+
131
+ `masterM` の2番目のインデックスが違います。正しくは以下のようになります。
132
+
133
+
134
+
135
+ ```java
136
+
137
+ if (quotient % 2 == 0) { // 偶数かどうかを確認
138
+
139
+ if (masterM[1][1].equals("○")) {
140
+
141
+ // ...省略...
142
+
143
+
144
+
145
+ } else {
146
+
147
+ if (masterM[0][1].equals("○")) {
148
+
149
+ ```
150
+
151
+
152
+
153
+ でも、これを直して試してみたのですが、期待した答えにならないかったですねぇ。うーん、仕様か期待している答えのどちらかが間違っているような気がします。
154
+
155
+
156
+
157
+ ちなみに、整数の除算は小数点以下切り捨てですが、浮動小数点型(double)の除算の場合は、小数点以下四捨五入や、繰上げも選べます。以下のようなコードを追加して、結果が、outA.csv、outB.csvのどちらになるかやってみましたが、整数除算の場合と、浮動小数点除算(四捨五入)のどちらの場合でも、答えが合わないです。
158
+
159
+
160
+
161
+ ```java
162
+
163
+ for (int i = 0; i < numC.length; i++) {
164
+
165
+
166
+
167
+ if (stA.equals(numC[i][0])) { // 入力の値と計算Cのキーの値の一致確認
168
+
169
+
170
+
171
+ int intA = Integer.valueOf(stA);
172
+
173
+ int intC = Integer.valueOf(numC[i][1]);
174
+
175
+ int intQ = intA / intC;
176
+
177
+ boolean intEven = intQ % 2 == 0;
178
+
179
+ int intMIndex = intEven ? 1 : 0;
180
+
181
+ String intOut = masterM[intMIndex][1].equals("yes") ? "outA" : "outB";
182
+
183
+
184
+
185
+ System.out.format("%d: int ---- A: %4d, C: %4d, Q: %4d, even(%d): %s ==> %s%n",
186
+
187
+ i, intA, intC, intQ, intQ, intEven, intOut);
188
+
189
+
190
+
191
+ double doubleA = Double.parseDouble(stA);
192
+
193
+ double doubleC = Double.parseDouble(numC[i][1]);
194
+
195
+ double doubleQ = doubleA / doubleC;
196
+
197
+ int doubleRoundedQ = (int)Math.round(doubleQ);
198
+
199
+ boolean doubleEven = doubleRoundedQ % 2 == 0;
200
+
201
+ int doubleMIndex = doubleEven ? 1 : 0;
202
+
203
+ String doubleOut = masterM[doubleMIndex][1].equals("yes") ? "outA" : "outB";
204
+
205
+
206
+
207
+ System.out.format("%d: double - A: %2.2f, C: %2.2f, Q: %2.2f, even(%d): %s ==> %s%n",
208
+
209
+ i, doubleA, doubleC, doubleQ, doubleRoundedQ, doubleEven, doubleOut);
210
+
211
+
212
+
213
+ quotient = Integer.valueOf(stA) / Integer.valueOf(numC[i][1]);
214
+
215
+ ```
216
+
217
+
218
+
219
+ **結果:**
220
+
221
+ (出力されたものは、桁が揃っておらず見づらかったので、編集して読みやすくしてます)
222
+
223
+
224
+
225
+ ```
226
+
227
+ 9: int ---- A: 10, C: 2, Q: 5, even(5): false ==> outA
228
+
229
+ 9: double - A: 10.00, C: 2.00, Q: 5.00, even(5): false ==> outA
230
+
231
+ 8: int ---- A: 9, C: 1, Q: 9, even(9): false ==> outA
232
+
233
+ 8: double - A: 9.00, C: 1.00, Q: 9.00, even(9): false ==> outA
234
+
235
+ 7: int ---- A: 8, C: 3, Q: 2, even(2): true ==> outB <<<
236
+
237
+ 7: double - A: 8.00, C: 3.00, Q: 2.67, even(3): false ==> outA >>>
238
+
239
+ 6: int ---- A: 7, C: 2, Q: 3, even(3): false ==> outA <<<
240
+
241
+ 6: double - A: 7.00, C: 2.00, Q: 3.50, even(4): true ==> outB >>>
242
+
243
+ 5: int ---- A: 6, C: 1, Q: 6, even(6): true ==> outB
244
+
245
+ 5: double - A: 6.00, C: 1.00, Q: 6.00, even(6): true ==> outB
246
+
247
+ 4: int ---- A: 5, C: 3, Q: 1, even(1): false ==> outA <<<
248
+
249
+ 4: double - A: 5.00, C: 3.00, Q: 1.67, even(2): true ==> outB >>>
250
+
251
+ 3: int ---- A: 4, C: 2, Q: 2, even(2): true ==> outB
252
+
253
+ 3: double - A: 4.00, C: 2.00, Q: 2.00, even(2): true ==> outB
254
+
255
+ 2: int ---- A: 3, C: 1, Q: 3, even(3): false ==> outA
256
+
257
+ 2: double - A: 3.00, C: 1.00, Q: 3.00, even(3): false ==> outA
258
+
259
+ 1: int ---- A: 2, C: 3, Q: 0, even(0): true ==> outB <<<
260
+
261
+ 1: double - A: 2.00, C: 3.00, Q: 0.67, even(1): false ==> outA >>>
262
+
263
+ 0: int ---- A: 1, C: 2, Q: 0, even(0): true ==> outB <<<
264
+
265
+ 0: double - A: 1.00, C: 2.00, Q: 0.50, even(1): false ==> outA >>>
266
+
267
+ ```
268
+
269
+
270
+
271
+ 切り捨てと、四捨五入では、<<< >>> でマークした所に違いがありますが、どちらも期待している答えとは違いますね。仕様について、確認してもらえないでしょうか?
272
+
273
+