空白行を含んだテキストファイルをよみこんで、それをそのまま表示するプログラムをつくりたいのですが、BufferedReaderのreadLineを使うとnullが返ってきてしまいます。どうすれば空白行ということがわかるのですか。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

 readLineは、空行ならば空の文字列を、テキストの終わりならばnullを返しますので、通常は[1]の方法で問題はありません。


しかし、以前に異なるプラットフォームの改行コードが混在するテキストを処理する時に、それと同じ体験をしたことがあります。
SMTPやHTTPのヘッダとボディの区切りは、プラットフォームに関係なく0x0D+0x0Aを使うことになっているので、
この場合にもそのような現象が起きるのではないでしょうか。
 そして、そのときは[2]の方法で対処できたと思います。

-----[1]-----

import java.io.*;

public class textout1 {

public static void main(String args[]) {

String Str1;

try {

BufferedReader BR = new BufferedReader(new FileReader(args[0]));

while ((Str1 = BR.readLine()) != null) System.out.println(Str1);

BR.close();

} catch(Exception ex) { System.out.println(ex.toString()); };

};

}

-----[2]-----

import java.io.*;

public class textout2 {

public static void main(String args[]) {

String Str1;

try {

BufferedReader BR = new BufferedReader(new FileReader(args[0]));

while(true) {
if ((Str1 = BR.readLine()) != null) System.out.println(Str1);
else if (!BR.ready()) break;
};

BR.close();

} catch(Exception ex) { System.out.println(ex.toString()); };

};

}
    • good
    • 0

私もあまりJavaは触っていませんが、EOFExceptionが出なければ空


行という判断をするんじゃないのでしょうか?
    • good
    • 1

常に次の行を見て、EOFかどうかチェックしては


どうでしょうか。
#あまりJavaは触っていないので・・・

ではでは☆
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QIOException ってどういうときに起こるのでしょうか?

IOException ってどういうときに起こるのでしょうか?

http://www.atmarkit.co.jp/fjava/rensai2/javaent12/javaent12.html
を見て勉強しています。

  catch ( IOException e) {
    System.out.println( "キーボードが故障しているのかもしれません" );
  }

と書いてあります。
ハード(キーボード)が故障しているのを Java のプログラムのレベル(ソフトウェア)で感知できるというのがよくわかりません。「

NumberFormatException の方はわかるのですが・・・

Aベストアンサー

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接続だったりするわけですけど、
InputStreamは、その入力元の情報を持っていないので、
データを読み取る際は常に
IOExceptionをキャッチするコードを書かなくてはいけません。
たとえ、絶対にIOエラーが発生しないストリームだとしても。

さらに付け加えるなら、
そもそも「標準入力=キーボード」であるとは限りません。
(一般的にはキーボードであることが多いですが。)
Javaでは、
System.setIn(InputStream)
を呼び出して、標準入力を変えてしまうことができますし、
標準入力を指定してプログラムを実行することができるOSもあります。

追伸1:
例外をキャッチしたときは、
スタックトレースをプリントすることをおすすめします。
catch (IOException e) {
e.printStackTrace();
}

追伸2:
そのプログラムでIOExceptionを発生させる最も簡単な方法は、
readLine()を呼び出す前に
標準入力(System.in)を閉じてしまうことです。
System.in.close();

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接...続きを読む

Qシンボルが見つかりませんというエラーが理解できません。

以下のようなじゃんけんゲームのプログラムを書いたのですが、「シンボルが見つかりません。」というエラーが表示されるのですが、エラーの意味が理解できず、解決できません。どこが間違っているのか教えていただけませんか。

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

public class janken extends Applet
implements Runnable, ActionListener {
private static final int EXTERNAL_BUFFER_SIZE = 128000;

Image image[] = new Image[3];
Thread t;
int index1 = 0;
int index2 = 0;
String msg = "";
String msg1 = "";

boolean state = false;
Button b1 = new Button("ぐー");
Button b2 = new Button("ちょき");
Button b3 = new Button("ぱー");

public void init(){
for(int i = 0; i<=2; i++){
img[i] = getImage(getDocumentBase(),"hanabi" + (i+1) + ".JPG");
}
add(b1);
add(b2);
add(b3);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
msg1 = "結果は・・";

}

public void paint(Graphics g){
g.drawImage(img[index1],350,30,this);
g.drawImage(img[index2],695,30,this);
g.drawString("コンピューター",420,300);
g.drawString("あなた",800,300);
g.drawString(msg,630,320);
g.drawString(msg1,550,320);
}

public void start(){
state = true;
t = new Thread(this);
t.start();

}

public void run(){
while(state){
index1++;
if(index1 == 3){
index1 = 0;
}
index2++;
if(index2 == 3){
index2 = 0;
}
repaint();
try {
Thread.sleep(60);
}catch(InterruptedException e) { }
}
}

public void actionPerformed(ActionEvent e){
if(state == false) {
start();
return;

}
state = false;
if(e.getSource() == b1) {
msg = "ぐー";
index2 = 0;
}

else if(e.getSource() == b2){
msg = "ちょき";
index2 = 1;
}

else if(e.getSource() == b3){
msg = "ぱー";
index2 = 2;
}
check();
repaint();
}

public void check() {
if(index1 == index2) msg ="あいこ";


else if (index1 == 0) {
if(index2 == 2) msg="あなたの勝ち";
else msg ="あなたの負け";
}

else if(index1 == 1) {
if(index2 == 0) msg="あなたの勝ち";
else msg="あなたの負け";
}

else if(index1 == 2) {
if(index2 == 1) msg="あなたの勝ち";
else msg="あなたの負け";
}

}
}

以下のようなじゃんけんゲームのプログラムを書いたのですが、「シンボルが見つかりません。」というエラーが表示されるのですが、エラーの意味が理解できず、解決できません。どこが間違っているのか教えていただけませんか。

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.File;

public class janken extends Applet
implements Runnable, ActionListener {
private static final int EXTERNAL_BUFFER_SIZE = 128000;

Image image[] = new Imag...続きを読む

Aベストアンサー

「シンボルを見つけられません。」というエラーの下に何か表示がありませんでしたか?そこにヒントがあると考えられます。
シンボルを見つけられませんといエラーが表示される主な理由は4つあります。
(1)クラス、メソッド、変数などの綴りミスや定義していない変数を使用している可能性がある。
(2)コンストラクタを呼び出すときに、newを忘れている可能性がある。(3)公開されていないメンバーを呼び出している可能性がある。
(4)必要なimport文を記述し忘れている可能性がある。
ここでのあなたのエラーは(1)番ではないでしょうか?上記ではimageとなっている変数がimgになっていますね。
これはエラー表示をよく見ることで意外と簡単に解決できるのです。
ゆっくり丁寧にエラー表示を見るように心がけることが大事ですよ。

Q「JAVAプログラミング」空白の削除について

JAVAで出力をするときに無意味な改行を削除したいのですがどうすればよいでしょうか?
for(;;) {
 String h = br.readLine();
 if( h == null) {
  break;
 }

 if((h != "") {
  fr.write(h);
 }
}

hには、テキストファイルから1行ずつ読み取った文字列が入っています。
ただ、時々、改行が入ることがあるのですが改行をなくして保存するにはどうすればよいでしょうか?
下記のようなファイル操作を例に教えていただけると幸いです。


読み込みファイル
------------














------------

結果の出力
------------










-------

Aベストアンサー

String tmp;
while((tmp = br.readLine())!=null){
 //書きたいものだったら出力する
 //たぶん文字列が含まれていたら書くのかな?
 if(tmp.length()>0){
   bw.write(tmp);
 }
}
br.close();←BufferedReader
bw.close();←BufferedWriter

QCSVファイルの特定の行だけを読み込みたいです。

例えば以下のようなCSV形式のデータが10000行あるとします。
 1,10,15,3
 2,1,5,1
 70,2,4,2
 2,4,5,6
 11,1,9,9
 ・・・

上記ファイルから、例えば9999行目を取得したい場合、
現在は以下のような手順で9998行をループで読み込んでから、
9999行目を取得しています。(エラー処理などは省いています)
 BufferedReader br = new BufferedReader(new FileReader("hoge.csv"));
 for( int i=0; i<9998; i++ ){ br.readLine(); }
 System.out.println("9999行目="+br.readLine());

ただし、上記の通りループを9998回まわし、
データを1行ずつ読み込むのは非常に効率が悪いです。
できれば、br.readLine(9999); といった感じで行数を直接指定できる方法があるならば、
無駄な処理を省けて見栄えも速度も良くなると思うのですが、
Javaの標準のクラスではこういったことは可能なのでしょうか?

私なりに調べてみたのですが調べ方が悪いのか知識が及ばないため、
こちらで質問させていただきました。
もしご存知の方がおられましたらアドバイスいただけますと助かります。
よろしくお願いします。

例えば以下のようなCSV形式のデータが10000行あるとします。
 1,10,15,3
 2,1,5,1
 70,2,4,2
 2,4,5,6
 11,1,9,9
 ・・・

上記ファイルから、例えば9999行目を取得したい場合、
現在は以下のような手順で9998行をループで読み込んでから、
9999行目を取得しています。(エラー処理などは省いています)
 BufferedReader br = new BufferedReader(new FileReader("hoge.csv"));
 for( int i=0; i<9998; i++ ){ br.readLine(); }
 System.out.println("9999行目="+br.readLine());

ただし、上記の通りル...続きを読む

Aベストアンサー

Javaはしばらくいじってないのであれですが・・・

仮にreadline(9999)というような関数があるとしても内部的には
for(int i=0;i<9998);i++){
br.readline()
}
と同じことをしていて スペック的にはほとんど変わらないはずです。
9999行目を読み込むためには 1行目から順に最初からファイルを読んでいって改行の数を数えてやる必要があるので・・・


見栄えがというのであれば自分でBufferedReader を継承して独自のクラスを作ってしまったらいかがでしょう?
readline(int line)だけ書いてやるだけだから5分とかからないし・・・


なおJavaは最近いじってないので標準関数でご希望のものがあるかはわかりませんが
自分だったらそんなことで悩んでる暇があったら自分で書いちゃいます。

Q空の文字列とnullと""

java初心者です。
空の文字列とnullと""の3つの関係がよくわかりません。

TextFieldを使った簡単なプログラムを作りました。そこで、”TextFieldに何も入力されていないこと”を判定する文を書こうと思ったのですが、どう書けばいいのか迷いました。

TextFieldのオブジェクトをtfとして、tf.getText()==""かtf.getText()==nullで大丈夫だと思いましたが、実行してみると、どちらを用いても判定できませんでした。結局、tf.getText().length()==0で判定できました。そこで、リファレンスを見ると、getText()はデフォルトで空の文字列を返すと、書いてありました。

したがって、「""とnullは空の文字列とは異なる」という理解に至ったのですが、では空の文字列とは何なのかという疑問がわいてきました。

また、自分は""とnullの違いもよくわかっていません。""とnullが異なるものである、ということはわかるのですが・・・

質問をまとめると
・空の文字列とは何なのか?
・空の文字列は""やnullとどう違うのか?
です。よろしくお願いします。

java初心者です。
空の文字列とnullと""の3つの関係がよくわかりません。

TextFieldを使った簡単なプログラムを作りました。そこで、”TextFieldに何も入力されていないこと”を判定する文を書こうと思ったのですが、どう書けばいいのか迷いました。

TextFieldのオブジェクトをtfとして、tf.getText()==""かtf.getText()==nullで大丈夫だと思いましたが、実行してみると、どちらを用いても判定できませんでした。結局、tf.getText().length()==0で判定できました。そこで、リファレンスを見ると、getText()はデフ...続きを読む

Aベストアンサー

tf.getText() == ""
では、オブジェクト比較になってしまうので、当然NGです。

"".equals(tf.getText())

とすれば良いでしょう。

空文字と呼ばれているものは、""と同じですよ。
Stringクラスで考えると、インスタンス化がされているが、中身の文字列が""の状態にあります。

nullは、そもそもオブジェクトすら設定されていない状態です。
例えばStringBufferクラスの変数を宣言しても、インスタンス化されていない状態、それがnullです。

Qyyyymmddからyyyy/mm/ddへの変換

いつもお世話になっております。
Aと言う変数にはyyyymmddの値が入っていて
Aをyyyy/mm/ddにしてBの変数に入れたい場合の処理がわかりません。
調べたところ、SimpleDateFormatクラスと言うものを使えばよいと言うことが判明しました。
しかし、今まで使ったことがないのでよくわかりません。
変数Aと変数BはどちらもString型です。
ご教授お願い致します。

Aベストアンサー

 こんにちは。

 本当に変数aの中の文字列が厳密にyyyyMMddの形式のなっているのなら、普通に

String b = a.substring(0, 4) + "/" + a.substring(4, 6) + "/" + a.substring(6, 8);

 これでいいと思いますが、いったんDate型にする必要があったり、ちゃんと日付として認識できるか確かめる必要がある場合は、

String a = "20051029";

SimpleDateFormat formatter = (SimpleDateFormat)DateFormat.getDateInstance();
formatter.applyPattern("yyyyMMdd");
try {
  Date date = formatter.parse(a);
  formatter.applyPattern("yyyy/MM/dd");
  String b = formatter.format(date);
  System.out.println(b);
}
catch (ParseException ex) {
  System.out.println("解析失敗");
}

 こんな感じでいいんじゃないでしょうか。

 こんにちは。

 本当に変数aの中の文字列が厳密にyyyyMMddの形式のなっているのなら、普通に

String b = a.substring(0, 4) + "/" + a.substring(4, 6) + "/" + a.substring(6, 8);

 これでいいと思いますが、いったんDate型にする必要があったり、ちゃんと日付として認識できるか確かめる必要がある場合は、

String a = "20051029";

SimpleDateFormat formatter = (SimpleDateFormat)DateFormat.getDateInstance();
formatter.applyPattern("yyyyMMdd");
try {
  Date date = formatter.p...続きを読む

Q改行の判定方法

改行のみが入っているかどうかの判定が行いたいのです。

String TextData;
if(TextData.equals(System.getProperty("line.separator"))){
  System.out.println("改行");
}

TextDataに改行だけ入っている可能性があるため、ifで判定してみたのですが、ひっかかりません。
どうやればよいのでしょうか。

Aベストアンサー

String lineSeparator = System.getProperty("line.separator");

if ( lineSeparator.equals(System.getProperty("line.separator"))){
System.out.println("true");
} else {
System.out.println("false");
}

実行するとtrueが表示されるので、質問者さんのTextDataに入っている値がLineSeparatorと違うんでしょうね。

問題の箇所をダンプしてみてはいかがでしょうか?(文字コードとかも)

Q文字列からダブルクオートの削除

お世話になります、

CSVからデータを取得してDBに書き込む処理を行っているのですが、CSVデータで型が文字のものはダブルクオート(")でくくっています。
(例)
"りんご",100,"円"
"ばなな",200,"ドル"

このままデータをStringTokenizerクラスを使用して取得した場合りんごは("りんご")のようにダブルクオートがついた状態で取得されてしまいます。
ダブルクオートを取り外す方法またはメソッドを教えていただきたいのですが、よろしくお願いします。

Aベストアンサー

以前作成した1行文字列をフィールド分割する関数ソースを載せておくので
参考にしてください。
もっといい方法があるのかもしれませんが、とりあえずここでは
一文字ずつ呼んでダブルクオートを削除し、又ダブルクオート内の
カンマはそのまま文字として使用するようにしてます。
面倒だったので文字内にダブルクオートを使用することは考慮に入れてません(^^;

ArrayList parsLine(String line){
 ArrayList fields = new ArrayList();
 if(line == null) return;
 boolean isQuort = false; //ダブルコーテーション内フラグ
 StringBuffer field = null;
 for(int i=0;i<line.length();i++){
  char code = line.charAt(i);
  if(isQuort){
//ダブルクオート内
   if(code == '\"'){
    isQuort = false;
   }
   else{
    if(field == null) field = new StringBuffer();
    field.append(code);
   }
  }
  else{
//ダブルクオート外
   if(code == '\"'){
    isQuort = true;
   }
   else if(code == ','){
    if(field == null) field = new StringBuffer();
    fields.add(field.toString());
    field = null;
   }
   else{
    if(field == null) field = new StringBuffer();
    field.append(code);
   }
  }
 }

 if(field != null){
  fields.add(field.toString());
 }
 return fields;
}

以前作成した1行文字列をフィールド分割する関数ソースを載せておくので
参考にしてください。
もっといい方法があるのかもしれませんが、とりあえずここでは
一文字ずつ呼んでダブルクオートを削除し、又ダブルクオート内の
カンマはそのまま文字として使用するようにしてます。
面倒だったので文字内にダブルクオートを使用することは考慮に入れてません(^^;

ArrayList parsLine(String line){
 ArrayList fields = new ArrayList();
 if(line == null) return;
 boolean isQuort = false; //ダ...続きを読む

Qinterface,extend,implementのちがい

お世話になります、

Javaを勉強しているのですが、
interface,extend,implementの使い分けがわかりません。

私の解釈としては、
(1)interfaceは、グローバル変数の定義、グローバルメソッドの定義(実装はしない)。

(2)extendは、extendクラスを親クラスとして親クラスの機能を使用できる。

(3)implementは…,implementもextendと同じような意味だと解釈しているんですが、違う点は、implementで定義してあるメソッドは、使用しなくても、実装しなければならないという点でしょうか?

とにかくこの3つのを使い分けるコツとかあれば教えてください。
よろしくお願いします。

Aベストアンサー

バラバラに理解してもしょうがないッス。

まず、
(1)interface と implements
(2)class と extends

が対応しているわけっす。

JavaはC++と違って、比較的言語仕様を「簡単」にしたので「多重継承」という
概念がないです。
多重継承っていうのは、複数のクラスを親クラスにして継承するってことですね。

たとえば、 「TextFieldクラス」と「Japaneseクラス」を多重継承すると、
「JTextFieldクラス」ができるっていうのが自然な考え方でしょう?

まぁ、例えば、日本語クラスであれば、getStringLength()メソッドなどが
あったほうが良いでしょうか。
このgetStringLength()メソッドは、2バイト文字も1バイト文字も「1文字」
と数えてくれると言う点で、まさに、日本語クラス用のメソッドだと言えるでしょう。

例えば、Java的に記述すると、、、
class Japanese {
public int getStringLength() {
  ・・・
return strlength;
 }
 ・・・
}

class TextField {
・・・
}

class JTextField extends TextField, extends Japanese {
・・・・
}

C++ではそのように実装するでしょう。
しかし、Javaにはこのような高度な機能はありません。

そこで、生まれた苦肉の策が、「interfaceとimplements」です。

interface Japanese {
public int getStringLength(); // interfaceは実装を含まない!
                 // すなわち「実装の継承」ができるわけではない。
}

class TextField {
・・・
}

class JTextField extends TextField implements Japanese {
・・・・
public int getStringLength() {
  ・・・
return strlength; //implementsの実装を「各クラスで」実装してやる必要がある。
 }
}


結局のところ、Javaでは、複数のクラスを親クラスには持ち得ないため、継承できなかったクラスは「各クラスで実装してやる必要性」があるのです。


ではどのように使うのが効果的か?

なまえのままです。「代表的なインターフェイス」にたいしてinterfaceを使うのが良いと思います。

例えば、プレイヤー系であれば、ビデオ・コンポ・ウォークマン・などにかかわらず、
interface controlpanel {
public play();
public stop();
public next();
public back();
}
というような基本的インターフェイスを「持っているべき」です。

こうすることで、それぞれのクラス宣言の際に、これらの「インターフェイスを持っているべきであり、実装されるべきである」ということを「強く暗示」することができます。
class videoplayer extends player implements controlpanel {
public play() {・・・}
public stop() {・・・}
public next() {・・・}
public back() {・・・}
}

こうすることで、同様のクラスを作成するユーザーは、
「プレイヤー系は、4つ操作が出来るコントロールパネルをインターフェイスとして持つべきなのだな!?」という暗示を受け取り、自分のクラスでもそれを模倣するでしょう。

class mp3player extends player implements controlpanel {
public play() {・・・}
public stop() {・・・}
public next() {・・・}
public back() {・・・}
}

また、これらのクラスを使用するユーザーも、「implements controlpanel」という
表記を見て、「4つの基本操作は押さえられているのだな!」という基本中の基本動作を抑えることが出来ます。

まとめると、クラスに「こういう特徴もたしてください!」「こういう特徴持ってますよ!」という一種の暗示的警告や方向性を与えることができるわけですね。

バラバラに理解してもしょうがないッス。

まず、
(1)interface と implements
(2)class と extends

が対応しているわけっす。

JavaはC++と違って、比較的言語仕様を「簡単」にしたので「多重継承」という
概念がないです。
多重継承っていうのは、複数のクラスを親クラスにして継承するってことですね。

たとえば、 「TextFieldクラス」と「Japaneseクラス」を多重継承すると、
「JTextFieldクラス」ができるっていうのが自然な考え方でしょう?

まぁ、例えば、日本語クラスであれば...続きを読む

Q文字列から数字を取り出す方法

質問があります。
例えば、テキストファイルから文章を一行ずつ読み込み、それをString型の変数に格納していきます。
その文から数字(整数で、何桁かはわからない。)を取り出し(ちなみにその数字の前後には特定の文字がついています)、変数に格納するというプログラムを作りたいのですが、具体的な方法がわかりません。
よろしければ是非教えてください!

Aベストアンサー

こんな感じですか?
数値以外を除きそのまま代入させます

String str = "ABCDABCD1234512345abcd";
int ret = Integer.parseInt(str.replaceAll("[^0-9]",""));
System.out.println(ret); //結果表示


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報