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

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

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

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

Q&A

解決済

5回答

469閲覧

数字以外の文字がある行を取得する + α

takumi00000

総合スコア11

Java

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

0グッド

0クリップ

投稿2018/03/05 06:18

編集2018/03/05 06:21

前提

数字以外を発見したら「数字以外が〇行目で見つかりました - InputMismatchException Error」と出力するプログラムです。

やりたいこと

上に示したように数字以外が見つかったときには、その旨の文章を出力するのですが、見つかった行で検査が止まってしまうので、そのまま続いて検査するようにしたいのですが、どうすれば良いのかわかりません。どなたか教えて頂けませんか? 入力されたデータの行数を取得するにはどうすれば良いのでしょうか?何か方法があれば教えてください。

該当のソースコード

Java

1import java.util.Scanner; 2import java.util.InputMismatchException; 3import java.util.NoSuchElementException; 4 5/* 6 * - How To Use - 7 * 1. 1行目に検査する行数を入力する 8 * 2. 2行目からデータを入力する 9 */ 10 11public class Main { 12 public static void main(String[] args){ 13 Scanner sc = new Scanner(System.in); 14 int a = 0; 15 try{ 16 int times = sc.nextInt(); 17 System.out.println(times + "回検査します"); 18 System.out.println("===== 出力結果 ====="); 19 try{ 20 for(a = 0;a < times; a++){ 21 int line = sc.nextInt(); 22 int code = Integer.valueOf(line); 23 } 24 } catch(InputMismatchException e) { 25 System.out.println("数字以外が" + (a+1) + "行目で見つかりました - InputMismatchException Error"); 26 } finally{ } 27 } catch(NoSuchElementException e) { 28 System.out.println("検査する回数を入力してください"); 29 } finally { } 30 } 31} 32

試したこと

力不足で、何をどのようにすれば良いのかわかりませんでした。

補足情報(FW/ツールのバージョンなど)

JDKをインストールできない状態で、paiza.ioを使用しています。

最後になりましたが、前回の質問で、不快にさせてしまった方々、申し訳ありませんでした。

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

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

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

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

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

guest

回答5

0

Javaを学び始めの方が標準ライブラリーにどんな機能があるかを殆ど知らずにいきなりpaizaの問題を解き始めると、「入力はjava.util.Scannerを使うもんだ」と思い込んでしまうのかも知れません。Scannerを使うことがいけないというわけではないですが、それはあくまで入力用の機能の一つです。Scannerのnext/nextIntなどのメソッドが便利に使える前提を考えてみますと・・・

  • 入力データはスペースなど都合のよい区切り文字で文字列や数値(の文字列表現)が分割されている
  • 入力データが数値(の文字列表現)なのか文字列なのかあらかじめわかっている
  • 今読み込んでいるのは何行目かは意識しなくてよい
  • 上の条件に合致しない場合は即座に「エラー」としてプログラムを終えていい

など。

また質問者さんは「やりたいことを正確に述べる」という点が若干不足しています。例えば

text

12 210 a b 20 3c

なんて入力があったとき10を読んだ後でnextIntはaを読もうとします。そこでエラーを検出したとして「3行目に数字でないものがある」と表示するとそれは間違いということになると思います。また、エラーの後継続するとしてその後どうしたいのでしょう?"b 20"という部分をスキップして次の行から継続したいのですか?それとも"b"もまたエラーであるというメッセージを出したいのでしょうか?どちらにするかで結果は変わってきますよ?


入力データの何行目なのかを正確に表示するためにはScannerクラスのnextLine以外を使うのは論理を難しくすることになります。特に「数値でないものが存在する可能性がある」「一行に空白文字で区切られた数値や文字列が複数個存在する可能性」を前提にするならなおのことです。

なんらかの前提を追加してnextIntを使える条件を整えるならよいですがそれは少々難しいので、素直に考えるなら以下の方針の方がよさそうです。

(A) Scanner#nextIntで直接数値を読もうとせずにまず行単位で読み込む
(B) 読み込む度に「今何行目を読んだか」を数えておく
(C) 読み込んだ行に対して「そこに数字以外の文字があるかどうか」を検査する


細かい点で恐縮ですが・・・「数字以外の文字があるか」の検査方法については解釈のしかたが微妙にわかれると思います。

S1: 「数字」とは「'0'~'9'の数字文字(=digit)」のこと
S2: 「数字」とは「整数値の文字列表現」のこと

質問者さんはおそらくS2を意図しておられるでしょう。しかし「数字以外の行」と聞いたとき何人かのプログラマーはS1であると解釈するのではないでしょうか?

例えば、以下のような行があったとするとS2の仕様ではNGですが、S1の仕様ではOKとせねばなりません。

111111111111111111111111111111111111111111

S2でよいならInteger#parseIntで検査できます。当然ながら-123なんて行もOKになります。これはintと言えますから。


回答なんだか指摘なんだか曖昧なコメントになってしまいましたが、「正確にどういうことをさせたいか」を詳しく考えるというのもプログラミングの大事な練習だと思いますのでそういう意味合いで受け取っていただければと思います。

投稿2018/03/05 07:57

編集2018/03/05 08:08
KSwordOfHaste

総合スコア18394

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

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

0

... 真にやりたかったたことは、数字以外の文字を消すこと ...

stream を使って書いてみました。

java

1import java.io.BufferedReader; 2import java.io.IOException; 3import java.io.InputStreamReader; 4 5public class Trance { 6 public static void main(String[] args) { 7 try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { 8 br.lines() 9 .map(line -> line.replaceAll("\D", "")) 10 .forEach(System.out::println); 11 } catch (IOException e) { 12 e.printStackTrace(); 13 } 14 } 15}

eclipse での実行例

イメージ説明

参考情報

  • Javaで1行ずつテキストデータを読み込むイディオムの変遷

http://argius.hatenablog.jp/entry/2015/06/06/234315

  • Java 8 Streams: An Intro to Filter, Map and Reduce Operations

https://www.sitepoint.com/java-8-streams-filter-map-reduce/

投稿2018/03/08 16:38

katoy

総合スコア22324

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

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

0

見つかった行で検査が止まってしまうので、そのまま続いて検査するようにしたい

tryブロックをfor文の中に放り込めば良いです。

Java

1for(a = 0; a < times; a++) { 2 int line = sc.nextInt(); 3 try { 4 int code = Integer.valueOf(line); 5 } catch(InputMismatchException e) { 6 System.out.println("数字以外が" + (a+1) + "行目で見つかりました - InputMismatchException Error"); 7 } 8}

入力されたデータの行数を取得するにはどうすれば良いのでしょうか?

前もって全行読み取って、その配列/リスト長を調べるのが一番楽かと。
ファイルが巨大な場合はメモリを圧迫しないように工夫が必要ですが。

投稿2018/03/05 06:24

LouiS0616

総合スコア35660

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

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

0

自己解決

私が真にやりたかったたことは、数字以外の文字を消すことであったので、よく考えてみると、下記のソースコードのようにすれば良いのかと思い、もう一度書いてみると、見事動作しました。

KSwordOfHasteさんの指摘通り、質問に「やりたいことを正確に述べる」ということが不足していました。回答してくださった御三方、非常に申し訳ありませんでした。また、そんな質問に対して、解決する方法や指摘を回答してくださり、ありがとうございました。


[ソースコード]

Java

1import java.io.BufferedReader; 2import java.io.InputStreamReader; 3import java.util.ArrayList; 4 5/* 6 * - How To Use - 7 * 検査したいデータを入力して実行するだけ 8 */ 9 10public class Main { 11 public static void main(String[] args)throws Exception{ 12 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 13 ArrayList<String> array = new ArrayList<String>(); 14 15 while(true){ 16 String line = br.readLine(); 17 if(line == null || line == " "){ 18 break; 19 } else { 20 if(line.matches("[0-9]{1,}")){ 21 array.add(line); 22 } else { 23 String replaced_line = line.replaceAll("[A-Za-z!#\$%&'\[\]\(\)=~\|\-\^`\{\}\*\+<>\?_@;,\.\/',]",""); 24 array.add(replaced_line); 25 } 26 } 27 } 28 29 for(String data : array){ 30 System.out.println(data); 31 } 32 33 } 34}

[入力例]

841 1e813 28130 12730 agja 381920 9qwd 182y38 3891u20jqdwio

[入力例に対する出力]

841 1813 28130 12730 381920 9 18238 389120

投稿2018/03/08 03:19

takumi00000

総合スコア11

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

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

0

forループ内でtry~catchブロックを追加するといいのでは?

try{ for(a = 0;a < times; a++){ try{ int line = sc.nextInt(); int code = Integer.valueOf(line); } catch(InputMismatchException e) { System.out.println("数字以外が" + (a+1) + "行目で見つかりました - InputMismatchException Error"); } finally{ } } } catch(NoSuchElementException e) { System.out.println("検査する回数を入力してください"); } finally { }

投稿2018/03/05 06:26

tkturbo

総合スコア5572

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問