プロが教えるわが家の防犯対策術!

お伺い致します。
CSVで取り込んだデータの抽出をしたいのですが、方法が見出せません。どの点を直せば宜しいのでしょうか。
具体的には取り込んだ郵便番号をカウントして(例:京都市,34)CSVファイルに出力するように出したいのですがカウントがうまくできません。(以下、コメントアウトしたものがありますが、今までのソースを記載します)
宜しく御願いします。

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.*;
public class test01 {
static String fname ="26KYOUTO.CSV";

public static void main(String[] args){
if(args.length>0) fname = args[0];
try {
BufferedReader reader =
new BufferedReader(new FileReader(fname));
BufferedWriter pw =
new BufferedWriter(new PrintWriter("orig.txt"));
String line = reader.readLine();
System.out.println(line);
pw.println("");
int n = 0;
int count = 0;
_/*
while(true) {
String line = reader.readLine();
if(line.equals("26101")) break;
count++;
}
*/
reader.close();
System.out.println("京都府北区=" +count );
} catch(FileNotFoundException e) {
System.out.println("ファイルがありません。");
} catch(IOException e) {
System.out.println("入出力エラーです。");
}
}
}

A 回答 (2件)

このコードをざっと見たところ、このプログラムの仕様は、


1.「26KYOUTO.CSV」というテキストファイルを開いて、
2.ファイルを1行ずつ読み込んでいき、
3.行の値が「26101」になるまで行数をカウントし、「26101」というデータのある行が出たらストップ。
4.その行までの行数を表示する。
という仕様に解釈できます。
これで合ってますか?

また、CSVファイルなのに、
>String line = reader.readLine();
で、行の値を読み込み、カンマを配列などに加工することもなく、
>if(line.equals("26101")) break;
で、行の値(つまりline)をそのままチェックに使ってますが、これも問題ないですか?

この回答への補足

neko_noko様
早速のご質問、アドバイス有難う御座います。
また、返信が遅くなり申し訳ありません。
お答えいたします。
1.26101、これは26101が郵便局のHPから京都府の「26KYOUTO.CSV」を取り出し、北区は共通の番号が「26101」だったのでこれをカウントすれば、北区の郵便番号が幾つあるかがわかるプログラムを作成中です。各市町村別にカウントしようとしています。
また「26101」は北区の郵便番号がなくなるまで振られています。
2.「CSVファイルなのに、・・・・」という点は、CSVファイルを取り込むことができても、その中にある特定の文字列をカウントする方法が
全くわからなかったので苦肉に策です。
import java.util.regex.Matcher;や
import java.util.regex.Pattern;を使い
カウントできるか現在取り組んでいますが、郵便番号の集計は遅々として進まない状態です。取り込んだデータをさらにデータ別(郵便番号の件数集計)をどうすればよいか・・・・・
何卒、宜しく御願いします。

補足日時:2007/08/01 23:27
    • good
    • 0
この回答へのお礼

neko_noko様
返信遅くなりました。
一応完成いたしましたので、ご報告致します。
26KYOUTO.CSVファイルの一行目の不要なファイルをカウントしないようにしなければなりませんが、このように完成しました。
今まで有難う御座いました。

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.*;
import java.util.StringTokenizer;

public class Csv_0809{
static String fname = "26KYOUTO.CSV";

public static void main(String[] args) {
if(args.length>0)fname = args[0];
try{
BufferedReader reader =
new BufferedReader(new FileReader(fname));
String line = reader.readLine();

String globalNumber = "";
int count = 1;
String address = "";
int rowcount = 0;
while(line != null) {
StringTokenizer st = new StringTokenizer(line,",");

String number = st.nextToken();

if(number.equals(globalNumber)) {
count++;
for(int i = 0; i < 7; i++){
address=st.nextToken();
}
} else {
if(rowcount != 0){
System.out.println(address + count);
}

count = 1;
globalNumber = number;
}

line = reader.readLine();
rowcount++;
}

reader.close();
}catch(FileNotFoundException e) {
System.out.println("ファイルがありません。");
}catch(IOException e){
System.out.println("入出力エラーです。");
}
}
}

お礼日時:2007/08/16 00:19

No1です。

およそ状況がつかめました。
まずは、1つの郵便番号のカウントができるようにしていきましょう。
で、なぜカウントがおかしいかですが、これはコメントになっているwhile文の問題です。

>if(line.equals("26101")) break;

となってますが、これだとlineが26101と一致した場合、
その次のbreakが効いて、whileループを抜けてしまいます。

テキストファイルを1行ずつ読み込んでいく場合のよくある書き方は次のような感じです。

String line = reader.readLine();
while(line!=null) {
 //ここに1行ごとに行う処理を書く
 
 //次の行を読み込み
 line = reader.readLine();
}

まず、whileに入る前に最初の行を読み込んでおきます。
whileが見る条件は読み込んだlineがnullかどうかです。
nullでなければwhileを続けます。
while内では、1行ごとに行う処理を書きます。
処理が長かったり複雑ならメソッドを呼び出すようにすると見やすくなります。
その後で、次の行を読み込むためにline = reader.readLine()を実行します。
これでlineは次の行を読み込みます。

1行ごとに行う処理ですが、とりあえずは読み込んだ文字が26101に一致すればカウントする、
ということにしておくなら、
 if(line.equals("26101")){
  count++;
 }
という感じでしょうか。これでとりあえずのカウントはできると思います。

ちなみにCSVなどのように特定の文字で分割されたデータを分割する場合は、
StringTokenizerクラスがよく使われます。
StringTokenizer st = new StringTokenizer(line, ",");
というようにすると、","で区切られた文字列の集合が取れます。
※ただし、このやり方は厳密には正しくないです。

集計に関してですが、プログラムだけでやるとすればかなり大変かもしれません。
もしかすると、いいやり方(アルゴリズム)があるかもしれないですが、
自分では思いつきませんでした。
可能ならデータベースに全てのデータを追加してクエリで集計、とした方が早いかもしれません。

この回答への補足

neko_noko様
ご返信、アドバイス有難う御座いました。
「集計に関してですが、プログラムだけでやるとすればかなり大変かもしれません。」という点、確かに自分もそう思いました。集計に関してはmysql(Java+mysqlという形で行おうと思います。経験はありませんが・・・)で挑戦してみようと思います。また具体的なアドバイス大変参考になりました。行ってみます。
お礼が遅くなってしまいますのでまずはご連絡させて頂きました。
詳細については、再度ご連絡いたします。
よろしく御願い致します。

補足日時:2007/08/03 01:06
    • good
    • 0

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