Java 使用txt输入文件和扫描仪处理空行
我的程序完成了。我需要的一件事是它处理空白行的方法。我读过其他文章,但没有一篇帮助我将它们实现到我自己的代码中。我在读取文件的循环中尝试了各种语法,但都不起作用。谁能帮帮我吗。这看起来应该比现在感觉的容易。我正试图在我的代码中实现这一点,但在实现时遇到了困难。下面是我的两个类和input.txt。按原样,此程序按预期运行。谢谢你的帮助Java 使用txt输入文件和扫描仪处理空行,java,error-handling,io,Java,Error Handling,Io,我的程序完成了。我需要的一件事是它处理空白行的方法。我读过其他文章,但没有一篇帮助我将它们实现到我自己的代码中。我在读取文件的循环中尝试了各种语法,但都不起作用。谁能帮帮我吗。这看起来应该比现在感觉的容易。我正试图在我的代码中实现这一点,但在实现时遇到了困难。下面是我的两个类和input.txt。按原样,此程序按预期运行。谢谢你的帮助 String line = in.nextLine(); while (line.length() == 0) { if (in.hasNext()) {
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
}
Product.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;
}
}
分解问题时,您会发现有两个主要问题:
而在.nextLine()中(in.hasNext)解决。要解决第二个问题,只需在发现行为空时添加一个continue
:
while (in.hasNextLine()) {
line = in.nextLine();
// skip blank lines
if (line.length() == 0) continue;
// do your magic
}
现在,如何把这个放到你的主程序中?如果我们能做到这一点,那就太好了:infle.nextNonBlankLine()
,对吗?所以,让我们创建我们自己的扫描仪,有这种方法
首先,我们想如何使用自己的扫描仪?一个例子是:
SkipBlankScanner in = new SkipBlankScanner(inFile);
while (in.hasNextNonBlankLine()) {
line = in.nextNonBlankLine();
}
不幸的是,Scanner
是一个final
类,因此我们无法扩展它来添加我们的功能。下一个最好的方法是使用委托:
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):
公共类ProductScanner{
私人Skipblank扫描仪;
私人产品;
公共产品扫描仪(SkipBlank扫描仪){
this.scanner=扫描器;
}
公共布尔hasNextProduct(){
下一个产品=新产品();
如果(填充(行->下一个.setTitle(行))&&
填充(行->下一个.setInventoryCode(行))&&
填充(行->下一个.setQuantity(整型.parseInt(行)))&&
填充(行->下一个.setPrice(Double.parseDouble(行)))&&
填充(行->下一个.setType(行))){
试一试{
while(scanner.hasNextNonBlankLine(){
int rating=Integer.parseInt(scanner.nextNonBlankLine());
如果(额定值<0){
产品=下一个;
返回true;
}
下一步。添加用户评级(评级);
}
}捕获(数字格式){
}
}
返回false;
}
专用布尔填充(使用者操作){
if(scanner.hasNextNonBlankLine(){
试一试{
action.accept(scanner.nextNonBlankLine());
返回true;
}捕获(例外e){
}
}
返回false;
}
公共产品下一个产品(){
产品结果=产品;
if(result==null&&hasNextProduct())
结果=产品;
如果(结果==null)
抛出新的非法状态异常();
product=null;
返回结果;
}
}
您的文件似乎没有任何空行(而且它似乎是固定格式);此外,您不应该将nextInt()
和nextLine()
混合使用……这会给您带来各种痛苦(因为nextInt()
不会占用新行)@ElliottFrisch如果我添加一个空行,它就不能像现在这样处理它。我需要它来处理它,以防出现一个空行。你能把它放在github的摘要中吗?@Ron我从来没有使用过github。这里有什么问题吗?如果我想玩,我就必须复制/粘贴它,把它打过来。制作摘要,使它更容易使用我有一些想法,但我想先检查一下
SkipBlankScanner in = new SkipBlankScanner(inFile);
while (in.hasNextNonBlankLine()) {
line = in.nextNonBlankLine();
}
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;
}
}
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;
}
}