【问题标题】:Reading from a file and splitting the line从文件中读取并拆分行
【发布时间】:2014-09-13 15:30:04
【问题描述】:

这里是我的书店练习最后一部分的说明:

通过 Bookstore 类的 read() 方法,可以读取有关出版商和书籍的信息并将其存储在相应的集合中。此方法接收文件路径作为参数。该文件是按字段组织的文本,由“;”相互分隔。 如果第一个字段分别包含字母“P”或“B”,则每一行都包含有关出版商或书籍的信息。 Publisher 行在第一个行之后包含字段名称、平均交付和电子邮件。 在第一行之后,书籍行包含标题、作者、年份、价格、出版商名称和数量等字段。 该方法必须忽略不符合此描述模式的行。

这里是我到目前为止创建的代码:

public void read(String dir) throws IOException, FileNotFoundException {
    String s;
    String name="", del="", email="";
    int delivery=0;
    String author="", title="", publisher="", yr="", qnt="", prc="";
    int year=0, quantity=0;
    double price=0.0;
    int ch = 0;
    BufferedReader br = new BufferedReader(new FileReader(dir));

    while((s=br.readLine())!=null){

        // Here I know I should put more conditions but I can't define in my mind "field" in a right way.

        if((s.charAt(0)!='P' && s.charAt(1)!=';') || (s.charAt(0)!='B' && s.charAt(1)!=';'))
            System.out.println("Line not conform");

        else if((s.charAt(0)=='P') && (s.charAt(1)==';')){
            for(int i=2; s.charAt(i)!=';'; i++){
                name += s.charAt(i);
                ch = i+2;
            }
            for(int i=ch; s.charAt(i)!=';'; i++){
                del += s.charAt(i);
                delivery = Integer.parseInt(del);
                ch = i+2;
            }
            for(int i=ch; i<s.length(); i++){
                email += s.charAt(i);
            }
            publishers.add(new Publisher(name, delivery, email));
            name=""; del=""; email="";
            ch=0; delivery=0;

        } else if((s.charAt(0)=='B') && (s.charAt(1)==';')){
            for(int i=2; s.charAt(i)!=';'; i++){
                title += s.charAt(i);
                ch = i+2;
            }
            for(int i=ch; s.charAt(i)!=';'; i++){
                author += s.charAt(i);
                ch = i+2;
            }
            for(int i=ch; s.charAt(i)!=';'; i++){
                yr += s.charAt(i);
                year = Integer.parseInt(yr);
                ch = i+2;
            }
            for(int i=ch; s.charAt(i)!=';'; i++){
                prc += s.charAt(i);
                price = Double.parseDouble(prc);
                ch = i+2;
            }
            for(int i=ch; s.charAt(i)!=';'; i++){
                publisher += s.charAt(i);
                ch = i+2;
            }
            for(int i=ch; i<s.length(); i++){
                qnt += s.charAt(i);
                quantity = Integer.parseInt(qnt);
            }

            Book book=null;
            for(int i=0; i<publishers.size(); i++){
                if(publisher.equals(publishers.get(i).getName())){
                    book = new Book(title, author, year, price, publisher);
                    books.add(book);
                }
            }
            libro.setQuantity(quantity);
            author=""; title=""; publisher=""; prc=""; yr=""; qnt="";
            ch=0; year=0; price=0; quantity=0;
        }
    }
}

就我现在而言,我可以正确存储出版商和书籍,但是最后一次测试失败了,因为我不知道如何用正确的代码表达字段的概念。 谁能帮帮我?

此外,我确信有一种更简单的方法来编写我所写的内容,但在我看来,这似乎是目前最好的解决方案。

更新

感谢 Aeshang,我能够修改和更正我的代码,现在一切正常! 还有一件事:如果有办法,谁能帮我简化它?

public void leggi(String dir) throws IOException, FileNotFoundException {
    String s;
    String name="", del="", email="";
    int delivery=0;
    String author="", title="", publisher="", yr="", qnt="", prc="";
    int year=0, quantity=0;
    double price=0.0;
    BufferedReader br = new BufferedReader(new FileReader(dir));

    while((s=br.readLine())!=null){
        boolean isOk=true;
        String[] splitted = s.split(";");

        if((splitted.length!=7 && splitted.length!=4) || (!splitted[0].equals("E") && !splitted[0].equals("L")))
            System.out.println("Line not conform");
        else if(splitted[0].equals("E")){

            name=splitted[1];

            if(splitted[2].startsWith("0")||splitted[2].startsWith("1")||splitted[2].startsWith("2")||
                    splitted[2].startsWith("3")||splitted[2].startsWith("4")||splitted[2].startsWith("5")||
                    splitted[2].startsWith("6")||splitted[2].startsWith("7")||splitted[2].startsWith("8")||
                    splitted[2].startsWith("9")){
                del=splitted[2];
                delivery=Integer.parseInt(del);
            } else isOk=false;

            email=splitted[3];

            if(isOk==true){
                publishers.add(new Publisher(name, delivery, email));
                name=""; del=""; email=""; delivery=0;
            } else System.out.println("Line not conform");

        } else if(splitted[0].equals("L")){

            title=splitted[1];

            author=splitted[2];

            if(splitted[3].startsWith("0")||splitted[3].startsWith("1")||splitted[3].startsWith("2")||
                    splitted[3].startsWith("3")||splitted[3].startsWith("4")||splitted[3].startsWith("5")||
                    splitted[3].startsWith("6")||splitted[3].startsWith("7")||splitted[3].startsWith("8")||
                    splitted[3].startsWith("9")){
                yr=splitted[3];
                year=Integer.parseInt(yr);
            } else isOk=false;

            if(splitted[4].startsWith("0")||splitted[4].startsWith("1")||splitted[4].startsWith("2")||
                    splitted[4].startsWith("3")||splitted[4].startsWith("4")||splitted[4].startsWith("5")||
                    splitted[4].startsWith("6")||splitted[4].startsWith("7")||splitted[4].startsWith("8")||
                    splitted[4].startsWith("9")){
                prc=splitted[4];
                price=Double.parseDouble(prc);
            } else isOk=false;

            publisher=splitted[5];

            if(splitted[6].startsWith("0")||splitted[6].startsWith("1")||splitted[6].startsWith("2")||
                    splitted[6].startsWith("3")||splitted[6].startsWith("4")||splitted[6].startsWith("5")||
                    splitted[6].startsWith("6")||splitted[6].startsWith("7")||splitted[6].startsWith("8")||
                    splitted[6].startsWith("9")){
                qnt=splitted[6];
                quantityt=Integer.parseInt(qnt);
            } else isOk=false;

            if(isOk==true){
                Book book=null;
                book = new Book(title, author, year, price, publisher);
                books.add(book);
                book.setQuantity(quantity);
                author=""; title=""; publisher=""; prc=""; yr=""; qnt="";
                year=0; price=0; quantity=0;
            } else System.out.println("Line not conform");
        }
    }
}

【问题讨论】:

    标签: java string file file-io bufferedreader


    【解决方案1】:

    你听说过拆分字符串吗?请使用以下语法

    String[] splitedString = s.split(";");
    

    那么你在循环中的代码可以这样改变

    String[] splitedString = s.split(";");
    if(splitedString[0].length==1 && !(splitedString[0].equalsIgnoreCase("p") || splitedString[0].equalsIgnoreCase("b"))) {
            System.out.println("Line not conform");
    } else if(splitedString[0].equalsIgnoreCase(p) && splitedString.length==5) {
                name = splitedString[1];
                average = splitedString[2];
                delivery = splitedString[3];
                email = splitedString[4];
            }
    

    等等……

    编辑:

    对于所有解析 int 和 parse double 的人,请更改它们。保持简单,删除包括 if 检查在内的所有代码,它们应该像

    一样简单
    try {
        delivery=Integer.parseInt(splitted[2].trim());
    } catch (NumberFormatException) {
        isOk=false;
    }
    

    【讨论】:

    • 使用正则表达式可能会得到更简洁(更高效)的代码
    • 目标达成!但是,出于好奇,我试图省略trim() 调用(因为我想理解它),结果是一样的。为什么你认为有必要?只是以防万一(在现实世界的编程中而不是在锻炼期间)我不知道没有空格?
    • Trim 基本上会删除字符串开头或结尾的所有空格......是的,它只是一个预防措施......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2013-09-08
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 2014-01-17
    相关资源
    最近更新 更多