java - 使用 txt 输入文件和扫描仪处理空行

标签 java error-handling io

我的程序已完成。我需要的一件事是它处理空白行的方法。我读过其他帖子,但没有一个能帮助我将它们实现到我自己的代码中。我在读取文件的循环中尝试了各种语法,但没有一个有效。有人能帮助我吗。这看起来应该比现在感觉更容易。我正在尝试将其实现到我的代码中,但遇到困难。下面是我的两个类和 input.txt。照原样,该程序按预期运行。感谢您的帮助。

String line = in.nextLine();
while (line.length() == 0) {
  if (in.hasNext()) {
     line = in.nextLine();
  } else {
    break;
  }
}
if (line.length() == 0) {
   // reaches the end of input file
}

产品.java

/**
 * Product
 * 
 *   A simple class framework used to demonstrate the design
 *   of Java classes.
 *   
 *   @author 
 *   @version 02042015
 */
import java.util.*;

public class Product {
    private String name;
    private String code;
    private int quantity;
    private double price;
    private String type;
    private ArrayList<Integer> userRatings;


    /*
     * Product constructor
     */
    public Product() {
        name = "";
        code = "";
        quantity = 0;
        price = 0.0;
        type = "";
        userRatings = new ArrayList<Integer>();

    }
     public Product(Product productObject) {
            this.name = productObject.getName();
            this.code = productObject.getInventoryCode();
            this.quantity = productObject.getQuantity();
            this.price = productObject.getPrice();
            this.type = productObject.getType();
            this.userRatings = new ArrayList<Integer>();
        }

    public Product(String name, String code, int quantity, double price, String type) {
        this.name = name;
        this.code = code;
        this.quantity = quantity;
        this.price = price;
        this.type = type;
        this.userRatings = new ArrayList<Integer>();
    }
    /*
     * setName
     *  @param name - new name for the product
     */
    public void setName(String name) {
        this.name = name;
    }

    /*
     * getName
     *  @return the name of the product
     */
    public String getName() {
        return name;
    }

    /*
     * setType
     *  @param type - the type of the product
     */
    public void setType(String type) {
        this.type = type;
    }

    /*
     * getType
     * @return - the product type
     */
    public String getType() {
        return type;
    }

    /*
     * setPrice
     * @param price - the price of the product
     */
    public void setPrice(double price) {
        this.price = price;
    }

    /*
     * getPrice
     * @return the price of the product
     */
    public double getPrice() {
        return price;
    }

    /*
     * setQuantity
     * @param quantity - the number of this product in inventory
     */
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    /*
     * getQuantity
     * @return the number of this product in inventory
     */
    public int getQuantity() {
        return quantity;
    }

    /*
     * setInventoryCode
     * @param code - the new inventory code for the product
     */
    public void setInventoryCode(String code) {
        if(code.length()!= 8){
            System.out.println("An invalid code has been entered. Please enter a code that is 8 characters in length.");
        }
        else{
        }
        this.code=code;
    }

    /*
     * getInventoryCode
     * @return the inventory code of the product
     */
    public String getInventoryCode() {
        return code;
    }

    /*
     * setRatings
     * @param code the new set of ratings for the product
     */
    public void setRatings(ArrayList<Integer> Ratings){
        this.userRatings = Ratings;
    }

    /*
     * getRatings
     * @return the ratings of the product
     */
    public ArrayList<Integer> getRatings(){
        return userRatings;
    }

    /*
     * addUserRating
     * NOTE: Each individual rating is stored with the product, so you need to maintain a list
     * of user ratings.  This method should append a new rating to the end of that list
     * @param rating - the new rating to add to this product
     */
    public void addUserRating(Integer rating1) {
        if(rating1 > 5 || rating1 < 0){
            System.out.println("You have entered an invalid rating. Please enter a rating between one and five stars.");
        }
        this.userRatings.add(rating1);
    }


    /*
     * getUserRating
     *  NOTE:  See note on addUserRating above.  This method should be written to allow you
     *  to access an individual value from the list of user ratings 
     * @param index - the index of the rating we want to see
     * @return the rating indexed by the value index
     */
    public int getUserRating(int index) {
        int a = this.userRatings.get(index);
        return a;
    }

    /*
     * getUserRatingCount
     *  NOTE: See note on addUserRating above.  This method should be written to return
     *  the total number of ratings this product has associated with it
     * @return the number of ratings associated with this product
     */
    public int getUserRatingCount() {
        int a = this.userRatings.size();
        return a;
    }

    /*
     * getAvgUserRating
     *  NOTE: see note on addUserRating above.  This method should be written to compute
     *  the average user rating on demand from a stored list of ratings.
     * @return the average rating for this product as a whole integer value (use integer math)
     */
    public String getAvgUserRating() {
         int sum = 0;
          String avgRating = "";
         if (userRatings.size() != 0){
          for (int i = 0; i < this.userRatings.size(); i++) {
              int a = getUserRating(i);
                sum += a;
          }
          double avg = sum/this.userRatings.size();
          if(avg >= 3.5){
              avgRating = "****";
          }
          else if(avg >= 2.5){
              avgRating = "***";
          }
          else if(avg >= 1.5){
              avgRating = "**";
          }
          else if(avg >= 0.5){
              avgRating = "*";
          }
          else{
          }
         }
         else{
             avgRating = "";
         }
          return avgRating;
}
}

Project02.java

/**
 *  Inventory Reporting Program
 * 
 *  A simple set of methods used to report and summarize
 *  the information read from an inventory file of product data
 *  
 *   @author 
 *   @version 02042015
 */

import java.util.*;
import java.io.*;

public class Project02 {

    public static void main(String[] args) {
        //Establish the scanner so user input can be properly read.
        Scanner keyboard = new Scanner(System.in); 
                System.out.print("Enter an inventory filename: ");
                String fname = keyboard.nextLine();
                ArrayList<Product> products = loadProducts(fname);
                generateSummaryReport(products);
                highestAvgRating(products);
                lowestAvgRating(products);
                largestTotalDollarAmount(products);
                smallestTotalDollarAmount(products);
    }

    public static void generateSummaryReport (ArrayList<Product> Products){
        int counter = 0;
        System.out.println("Product Inventory Summary Report");
        System.out.println("----------------------------------------------------------------------------------");
        System.out.println();
        System.out.printf("%-33s%-10s%-6s%-7s%-7s%-7s%-7s", "Product Name", "I Code", "Type", "Rating", "# Rat.", "Quant.", "Price");
        System.out.println();
        System.out.printf("%-33s%-10s%-6s%-7s%-7s%-7s%-7s", "-------------------------------", "---------", "----", "------", "------", "------", "------");
        System.out.println();
    while(counter < Products.size()){
        System.out.printf("%-33s%-10s%-6s%-7s%6s%7s%7s", Products.get(counter).getName(), Products.get(counter).getInventoryCode(), Products.get(counter).getType(), Products.get(counter).getAvgUserRating(), Products.get(counter).getUserRatingCount(), Products.get(counter).getQuantity(), Products.get(counter).getPrice());
        System.out.println();
        counter++;
    }
    System.out.println("----------------------------------------------------------------------------------");
    System.out.println("Total products in the database: " + Products.size());
}


    /*
     * loadProducts
     *  Given a filename, opens the file and reads Products from
     *  the file into an ArrayList of Product objects.  Returns
     *  the ArrayList.
     *  
     *  
     *  @param fname - String containing the input file name
     *  @return - An ArrayList of Product objects
     */
    public static ArrayList<Product> loadProducts(String fname) {
        int a = 0;
        Integer b = 0;
        ArrayList<Product> products = new ArrayList<Product>();
        try {
        Scanner inFile = new Scanner(new File(fname));
        while (inFile.hasNext()) {
            int counter = 0;
            String name = inFile.nextLine();
            String code = inFile.nextLine();
            int quantity = inFile.nextInt();
            double price = inFile.nextDouble();
            String type = inFile.next();
            Product productObject = new Product(name, code, quantity, price, type);
            while(inFile.hasNextInt() && counter==0){
                a = inFile.nextInt();
                if(a != -1){
                b = new Integer(a);
                productObject.addUserRating(b);
                }
                else{
                counter = 1;
                }
            }
            products.add(productObject);
            if(inFile.hasNext()){
            inFile.nextLine();
        }
        }
        inFile.close();
    }
        catch (FileNotFoundException e) {
            System.out.println("ERROR: " + e);
        }
        return products;
}   
    //Finds the item with the highest average user rating in stock
    public static void highestAvgRating(ArrayList<Product> Products){
        int counter = 0;
        int a = 1;
        while (counter <= Products.size()-1){
            if(Products.get(counter).getAvgUserRating().length() > Products.get(a).getAvgUserRating().length()){
                a = counter;
            }
            else{
            }
            counter++;
        }
            System.out.println("Highest Average User Rating In Stock: " + Products.get(a).getName() + " ("+Products.get(a).getAvgUserRating() + ")");   
    }

    //Finds the item with the lowest average user rating in stock
    public static void lowestAvgRating(ArrayList<Product> Products){
        int counter = 0;
        int a = 1;
        while (counter <= Products.size()-1){
            if(Products.get(counter).getAvgUserRating().length()<Products.get(a).getAvgUserRating().length()){
                a=counter;
            }
            else{
            }
            counter++;
        }
            System.out.println("Lowest Average User Rating In Stock: "+Products.get(a).getName() + " ("+Products.get(a).getAvgUserRating() + ")");  
    }

    //Finds the item with the largest total dollar amount in inventory (quantity * price)
    public static void largestTotalDollarAmount(ArrayList<Product> Products){
        int counter = 0;
        int a = 1;
        while (counter <= Products.size()-1){
            if((Products.get(counter).getPrice())*(Products.get(counter).getQuantity()) > ((Products.get(a).getPrice())*(Products.get(a).getQuantity()))){
                a=counter;
            }
            else{
            }
            counter++;
        }
            System.out.println("Item With The Largest Total Dollar Amount In Inventory: " + Products.get(a).getName() + " ($" + ((Products.get(a).getPrice())*(Products.get(a).getQuantity())) + ")");  
    }

    //Finds the item with the smallest total dollar amount in inventory (quantity * price)
    public static void smallestTotalDollarAmount(ArrayList<Product> Products){
        int counter = 0;
        int a = 1;
        while (counter <= Products.size()-1){
            if((Products.get(counter).getPrice())*(Products.get(counter).getQuantity()) < ((Products.get(a).getPrice())*(Products.get(a).getQuantity()))){
                a=counter;
            }
            else{
            }
            counter++;
        }
            System.out.println("Item With The Smallest Total Dollar Amount In Inventory: " + Products.get(a).getName() + " ($" + ((Products.get(a).getPrice())*(Products.get(a).getQuantity())) + ")"); 
    }
}

输入.txt

The Shawshank Redemption
C0000001
100
19.95
DVD
4
5
3
1
-1
The Dark Knight
C0000003
50
19.95
DVD
5
2
3
-1
Casablanca
C0000007
137
9.95
DVD
5
4
5
3
-1
The Girl With The Dragon Tattoo
C0000015
150
14.95
Book
4
4
2
-1
Vertigo
C0000023
55
9.95
DVD
5
5
3
5
2
4
-1
A Game of Thrones
C0000019
100
8.95
Book
-1

最佳答案

当你分解你的问题时,你会发现有两个主要问题:

  1. 逐行读取输入
  2. 跳过空行。

第一个问题可以通过 while (in.hasNext) in.nextLine() 解决。要解决第二个问题,只需在发现该行为空时添加继续:

while (in.hasNextLine()) {
    line = in.nextLine();
    // skip blank lines
    if (line.length() == 0) continue;
    // do your magic
}

现在,如何将其放入您的主程序中?如果我们能以某种方式做到这一点那就太好了:inFile.nextNonBlankLine(),对吧?因此,让我们创建自己的具有该方法的扫描仪!

首先,我们想如何使用自己的扫描仪?一个例子可能是:

SkipBlankScanner in = new SkipBlankScanner(inFile);
while (in.hasNextNonBlankLine()) {
    line = in.nextNonBlankLine();
}

不幸的是,Scanner 是一个final 类,因此我们无法扩展它来添加我们的功能。下一个最好的办法是使用委托(delegate):

public class SkipBlankScanner {
    private Scanner delegate;
    private String line;

    public SkipBlankScanner(Scanner delegate) {
         this.delegate = delegate;
    }

    public boolean hasNextNonBlankLine() {
        while (delegate.hasNextLine())
            // return true as soon as we find a non-blank line:
            if ((line = delegate.nextLine()).length > 0)
                 return true;
        // We've reached the end and didn't find any non-blank line:
        return false;
    }

    public String nextNonBlankLine() {
        String result = line;
        // in case we didn't call "hasNextNonBlankLine" before:
        if (result == null && hasNextNonBlankLine())
            result = line;
        // try to read past the end:
        if (result == null) throw new IllegalStateException();
        line = null;
        return result;
    }
}

现在你就拥有了,你自己的扫描仪将忽略空白行!

您可以更进一步,创建一个扫描仪来扫描整个产品,例如(使用一些 Java-8):

public class ProductScanner {
    private SkipBlankScanner scanner;
    private Product product;

    public ProductScanner(SkipBlankScanner scanner) {
        this.scanner = scanner;
    }

    public boolean hasNextProduct() {
        Product next = new Product();
        if (fill(line -> next.setTitle(line)) &&
            fill(line -> next.setInventoryCode(line)) &&
            fill(line -> next.setQuantity(Integer.parseInt(line))) &&
            fill(line -> next.setPrice(Double.parseDouble(line))) &&
            fill(line -> next.setType(line))) {

            try {
                while (scanner.hasNextNonBlankLine() {
                    int rating = Integer.parseInt(scanner.nextNonBlankLine());
                    if (rating < 0) {
                        product = next;
                        return true;
                    }
                    next.addUserRating(rating);
                }
            } catch (NumberFormatException e) {
            }
        }
        return false;
    }

    private boolean fill(Consumer<String> action) {
        if (scanner.hasNextNonBlankLine() {
            try {
                action.accept(scanner.nextNonBlankLine());
                return true;
            } catch (Exception e) {
            }
        }
        return false;
    }

    public Product nextProduct() {
        Product result = product;
        if (result == null && hasNextProduct())
            result = product;
        if (result == null)
            throw new IllegalStateException();
        product = null;
        return result;
    }
}

关于java - 使用 txt 输入文件和扫描仪处理空行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28312982/

相关文章:

java - 如何在保持当前连接的情况下连接到多个服务器?

java - 异常 : java. lang.RuntimeException 在 android.app.ActivityThread.handleReceiver

c++ - 为什么 fseek 不起作用?

python - 读取 tar 文件的 HTTPResponse

c# - 如何读取流的所有字节但最后 8 个字节

java - 从 .mp3 或任何合适的格式到 MIDI 的声音转换

java - 使用特定版本的 JRE 执行 JAR 文件

php - PHP错误处理函数或类?

javascript - Rails 在 application.js 中找不到文件

swift - 使用重复的primaryKey保存到Realm时未捕获错误